Java+AI驅(qū)動實現(xiàn)PDF文件數(shù)據(jù)提取與解析
體檢結(jié)束后,面對報告中繁多的指標(biāo)和專業(yè)術(shù)語,許多人常會感到困惑:這些數(shù)據(jù)代表什么含義?是否存在健康風(fēng)險?需要采取哪些應(yīng)對措施?人工解讀不僅依賴專業(yè)知識,效率也相對低下。本文將分享一套基于 AI 的體檢報告智能評估方案,詳細(xì)介紹從 PDF 上傳、內(nèi)容提取到 AI 分析、數(shù)據(jù)存儲的全流程自動化實現(xiàn)方法。

一、核心流程:從上傳到評估的完整鏈路
本系統(tǒng)的核心目標(biāo)是:用戶上傳體檢報告 PDF 后,系統(tǒng)自動解析內(nèi)容,調(diào)用 AI 生成結(jié)構(gòu)化評估結(jié)果,最終存儲到數(shù)據(jù)庫供前端展示。整體流程分為兩大步驟:
- 上傳體檢報告:用戶上傳 PDF 文件 → 存儲至阿里云 OSS → 提取 PDF 文本內(nèi)容 → 臨時緩存到 Redis → 向前端返回上傳結(jié)果。
- 生成評估結(jié)果:用戶確認(rèn)解析 → 從 Redis 讀取文本內(nèi)容 → 調(diào)用 AI 大模型生成 JSON 格式評估結(jié)果 → 存儲到數(shù)據(jù)庫 → 完成智能評估。
技術(shù)棧選擇:采用 Apache PDFBox 解析 PDF 文本,百度千帆大模型進(jìn)行智能分析,Redis 用于臨時緩存,MySQL 存儲最終結(jié)果,阿里云 OSS 存儲原始文件。

二、第一步:解析 PDF,提取體檢報告內(nèi)容
PDF 是體檢報告常見的格式,但直接讀取其中的文本存在一定難度。我們選擇 Apache PDFBox 這一成熟的開源 PDF 處理庫來提取文本內(nèi)容。
1. 引入依賴
在項目的 common 模塊中添加 PDFBox 依賴(以 Maven 為例):
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.24</version>
</dependency>
2. 封裝 PDF 工具類
為方便調(diào)用,封裝PDFUtil工具類,其核心方法pdfToString接收文件輸入流,返回提取的文本:
public class PDFUtil {
public static String pdfToString(InputStream inputStream) {
PDDocument document = null;
try {
// 加載PDF文檔
document = PDDocument.load(inputStream);
// 創(chuàng)建文本提取器
PDFTextStripper pdfStripper = new PDFTextStripper();
// 提取文本并返回
return pdfStripper.getText(document);
} catch (IOException e) {
e.printStackTrace();
} finally {
// 關(guān)閉資源
if (document != null) {
try {
document.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
}
3. 測試驗證
找一份體檢報告 PDF,編寫簡單的測試類驗證文本提取功能:
public class PDFUtilTest {
public static void main(String[] args) throws FileNotFoundException {
FileInputStream fileInputStream = new FileInputStream("C:\tmp\體檢報告-劉愛國-男-69歲.pdf");
String result = PDFUtil.pdfToString(fileInputStream);
System.out.println(result); // 打印提取的文本內(nèi)容
}
}
若控制臺能輸出 PDF 中的文字,則表明解析成功。
三、第二步:集成百度千帆大模型,讓 AI 做專業(yè)解讀
提取文本后,需借助 AI 基于內(nèi)容生成結(jié)構(gòu)化評估。我們選擇百度千帆大模型(ERNIE-4.0-8K-Preview),它在醫(yī)療領(lǐng)域的理解能力較強(qiáng),且支持 JSON 格式輸出,便于后續(xù)解析。
1. 準(zhǔn)備工作:注冊與認(rèn)證
注冊百度智能云賬號,完成個人實名認(rèn)證(需在手機(jī)端 APP 操作)。
創(chuàng)建 AccessKey:在控制臺的 “安全認(rèn)證” 中生成,用于 API 調(diào)用時的身份驗證。
注意:新用戶有 20 元代金券,足夠測試使用;調(diào)用前需確保已開通目標(biāo)模型的付費(fèi)權(quán)限。
2. 引入 SDK 依賴
在 common 模塊中添加百度千帆 SDK:
<dependency>
<groupId>com.baidubce</groupId>
<artifactId>qianfan</artifactId>
<version>0.1.6</version>
</dependency>
3. 封裝 AI 調(diào)用工具
為便于復(fù)用,封裝AIModelInvoker類,統(tǒng)一處理大模型調(diào)用邏輯:
@Component
@Slf4j
public class AIModelInvoker {
@Autowired
private BaiduAIProperties baiduAIProperties; // 配置類,讀取accessKey等參數(shù)
public String qianfanInvoker(String prompt) {
// 初始化千帆客戶端
Qianfan qianfan = new Qianfan(baiduAIProperties.getAccessKey(), baiduAIProperties.getSecretKey());
// 調(diào)用模型
ChatResponse response = qianfan.chatCompletion()
.model(baiduAIProperties.getQianfanModel()) // 模型名稱,如ERNIE-4.0-8K-Preview
.addMessage("user", prompt) // 傳入提示詞
.temperature(0.7) // 控制輸出隨機(jī)性(0-1之間,值越小越穩(wěn)定)
.maxOutputTokens(2000) // 最大輸出長度
.responseFormat("json_object") // 指定返回JSON格式
.execute();
return response.getResult(); // 返回AI生成的結(jié)果
}
}
其中BaiduAIProperties用于讀取配置文件中的參數(shù)(accessKey、secretKey、模型名等),避免硬編碼:
@Data
@Configuration
@ConfigurationProperties(prefix = "baidu")
public class BaiduAIProperties {
private String accessKey;
private String secretKey;
private String qianfanModel;
}
在application.yml中配置參數(shù):
baidu: accessKey: 你的accessKey secretKey: 你的secretKey qianfanModel: ERNIE-4.0-8K-Preview
4. 關(guān)鍵:設(shè)計提示詞(Prompt)
要讓 AI 生成符合要求的結(jié)構(gòu)化結(jié)果,提示詞的設(shè)計至關(guān)重要。一個優(yōu)質(zhì)的提示詞需明確:AI 的角色、任務(wù)要求、輸入內(nèi)容、輸出格式。
針對體檢報告解析,設(shè)計的提示詞如下(核心部分):
請以專業(yè)醫(yī)生的視角分析以下體檢報告,完成以下任務(wù):
1. 提取總檢日期;
2. 給出風(fēng)險等級(健康/提示/風(fēng)險/危險/嚴(yán)重危險)和健康指數(shù)(0-100分);
3. 計算各風(fēng)險等級的占比(保留兩位小數(shù));
4. 列出異常數(shù)據(jù)(結(jié)論、項目名、結(jié)果、參考值、單位、解讀、建議);
5. 給8大系統(tǒng)(呼吸、消化等)打分(0-100分);
6. 總結(jié)報告核心結(jié)論。
輸出要求:僅返回JSON,格式如下:
{
"totalCheckDate": "YYYY-MM-DD",
"healthAssessment": {
"riskLevel": "healthy/caution/risk/danger/severeDanger",
"healthIndex": XX.XX
},
"riskDistribution": { ... },
"abnormalData": [ ... ],
"systemScore": { ... },
"summarize": "總結(jié)內(nèi)容"
}
提示詞中明確了 AI 的 “醫(yī)生” 角色,列出了具體任務(wù),并嚴(yán)格規(guī)定了 JSON 格式,確保后續(xù)能直接解析。
四、API 接口開發(fā):從上傳到存儲的完整實現(xiàn)
具備 PDF 解析和 AI 調(diào)用的基礎(chǔ)后,開發(fā)實際的業(yè)務(wù)接口,實現(xiàn) “上傳報告→AI 評估→存儲結(jié)果” 的全流程。
1. 數(shù)據(jù)庫設(shè)計
首先創(chuàng)建health_assessment表,存儲評估結(jié)果,核心字段包括:
老人基本信息(姓名、身份證號、年齡、性別等);
體檢信息(體檢機(jī)構(gòu)、報告 URL、總檢日期等);
AI 評估結(jié)果(健康指數(shù)、風(fēng)險等級、異常數(shù)據(jù)、系統(tǒng)評分等,以 JSON 格式存儲)。
2. 上傳體檢報告接口
用戶上傳 PDF 時,需將文件存儲到阿里云 OSS,并提取文本緩存到 Redis(供后續(xù) AI 調(diào)用)。
核心代碼(Controller 層):
@ApiOperation("健康文檔上傳")
@PostMapping("/upload")
public AjaxResult uploadFile(MultipartFile file, String idCardNo) throws Exception {
try {
// 上傳到OSS,獲取文件URL
String url = aliyunOSSOperator.upload(file.getBytes(), file.getOriginalFilename());
// 提取PDF文本
String content = PDFUtil.pdfToString(file.getInputStream());
// 緩存到Redis(key:idCardNo,便于后續(xù)關(guān)聯(lián))
redisTemplate.opsForHash().put("healthReport", idCardNo, content);
// 返回上傳結(jié)果
return AjaxResult.success().put("url", url).put("originalFilename", file.getOriginalFilename());
} catch (Exception e) {
return AjaxResult.error(e.getMessage());
}
}
3. 生成評估結(jié)果接口
用戶確認(rèn)后,從 Redis 讀取文本,調(diào)用 AI 生成結(jié)果,解析后存儲到數(shù)據(jù)庫。
核心代碼(Service 層):
@Override
public Long insertHealthAssessment(HealthAssessmentDto dto) {
// 1. 從Redis獲取PDF文本
String content = (String) redisTemplate.opsForHash().get("healthReport", dto.getIdCard());
if (StringUtils.isEmpty(content)) {
throw new BaseException("請先上傳體檢報告");
}
// 2. 組裝提示詞(結(jié)合dto信息和PDF文本)
String prompt = buildPrompt(content, dto);
// 3. 調(diào)用AI生成評估結(jié)果
String aiResult = aIModelInvoker.qianfanInvoker(prompt);
if (StringUtils.isEmpty(aiResult)) {
throw new BaseException("AI分析失敗");
}
// 4. 解析AI返回的JSON
HealthReportVo reportVo = JSONUtil.toBean(aiResult, HealthReportVo.class);
// 5. 保存到數(shù)據(jù)庫
HealthAssessment assessment = convertToEntity(reportVo, dto);
save(assessment);
return assessment.getId();
}
其中convertToEntity方法將 AI 生成的HealthReportVo轉(zhuǎn)換為數(shù)據(jù)庫實體HealthAssessment,并補(bǔ)充用戶基本信息(如通過身份證號解析年齡、性別等)。
五、總結(jié)與優(yōu)化
通過上述步驟,我們實現(xiàn)了從 PDF 體檢報告上傳到 AI 智能評估、結(jié)果存儲的完整系統(tǒng)。其核心亮點(diǎn)包括:
利用 PDFBox 高效提取文本,解決 PDF 解析難題;
借助百度千帆大模型,將非結(jié)構(gòu)化文本轉(zhuǎn)化為結(jié)構(gòu)化 JSON;
采用 Redis 臨時緩存、OSS 存儲文件,保證流程流暢。
后續(xù)可優(yōu)化的方向:
增加 PDF 表格識別功能(部分報告用表格展示指標(biāo),需特殊處理);
優(yōu)化提示詞,提高 AI 對罕見指標(biāo)的解讀準(zhǔn)確性;
增加異步處理機(jī)制(AI 調(diào)用可能耗時,用異步任務(wù)避免前端超時)。
以上就是Java+AI驅(qū)動實現(xiàn)PDF文件數(shù)據(jù)提取與解析的詳細(xì)內(nèi)容,更多關(guān)于Java PDF數(shù)據(jù)提取的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
mybatis-plus之如何實現(xiàn)in嵌套sql
這篇文章主要介紹了mybatis-plus之如何實現(xiàn)in嵌套sql問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03
springboot整合nacos,如何讀取nacos配置文件
這篇文章主要介紹了springboot整合nacos,如何讀取nacos配置文件問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11
Jenkins服務(wù)器更新密鑰后任務(wù)構(gòu)建不了的排查實錄與解決方案
在一次生產(chǎn)環(huán)境的 SSH 密鑰輪換中,我遇到了一個極其令人困惑的問題:在 Jenkins 服務(wù)器上手動執(zhí)行 ssh -i 命令測試新密鑰到目標(biāo)服務(wù)器,直接報 Permission denied,本文記錄了完整的排查過程,希望能幫助遇到類似故障的運(yùn)維人員快速定位問題,需要的朋友可以參考下2026-05-05
Java/Android 獲取網(wǎng)絡(luò)重定向文件的真實URL的示例代碼
本篇文章主要介紹了Java/Android 獲取網(wǎng)絡(luò)重定向文件的真實URL的示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-11-11
Spring的Xml和JavaConfig 擴(kuò)展哪個好用
今天給大家介紹基于注解的Spring擴(kuò)展,Spring的Xml和JavaConfig 擴(kuò)展的配置方法,關(guān)于Spring的Xml和JavaConfig 擴(kuò)展你會選哪個呢,帶著這個問題一起通過本文學(xué)習(xí)下吧2021-05-05

