網(wǎng)站建設項目目標描述怎么做招投標網(wǎng)站
鶴壁市浩天電氣有限公司
2026/01/24 05:04:44
網(wǎng)站建設項目目標描述,怎么做招投標網(wǎng)站,深圳知名網(wǎng)站建設價格,游戲網(wǎng)站開發(fā)什么意思基于 Apache POI 的體檢報告 Word 生成實戰(zhàn)文檔一 項目目標與總體設計
目標#xff1a;基于模板快速生成排版規(guī)范的體檢報告#xff0c;支持文本替換、動態(tài)表格、圖片插入#xff0c;并可一鍵導出 PDF 用于歸檔與打印。技術(shù)選型#xff1a;
Apache POI XWPF#xff1a;操作…基于 Apache POI 的體檢報告 Word 生成實戰(zhàn)文檔一 項目目標與總體設計目標基于模板快速生成排版規(guī)范的體檢報告支持文本替換、動態(tài)表格、圖片插入并可一鍵導出PDF用于歸檔與打印。技術(shù)選型Apache POI XWPF操作.docx模板完成占位符替換、表格行循環(huán)、圖片插入等。LibreOffice headless將.docx轉(zhuǎn)換為.pdf跨平臺、穩(wěn)定可靠。工程結(jié)構(gòu)建議模板resources/templates/health_report_template.docx領(lǐng)域模型體檢人信息、體檢項目結(jié)果、影像圖片等服務模板解析、數(shù)據(jù)填充、PDF 轉(zhuǎn)換、HTTP 下載關(guān)鍵約束模板必須使用.docxXWPF 不支持直接操作.doc占位符需保證在同一XWPFRun內(nèi)避免替換失敗。二 快速開始與最小可用示例Maven 依賴建議版本 ≥5.2.3dependencygroupIdorg.apache.poi/groupIdorg.apache.poi/groupIdartifactIdpoi-ooxml/artifactIdversion5.2.3/version/dependency最小可用流程讀取模板 → 替換占位符 → 寫出文件// 1) 讀取模板try(InputStreamisnewClassPathResource(templates/health_report_template.docx).getInputStream();XWPFDocumentdocnewXWPFDocument(is)){// 2) 簡單文本替換占位符格式${key}MapString,StringparamsMap.of(name,張三,gender,男,age,28,examDate,2025-12-01);replaceTextInDoc(doc,params);// 3) 寫出 .docxtry(FileOutputStreamoutnewFileOutputStream(target/體檢報告_張三.docx)){doc.write(out);}}占位符替換工具方法核心要點逐段遍歷逐 Run 替換避免跨 Run 失效publicstaticvoidreplaceTextInDoc(XWPFDocumentdoc,MapString,Stringparams){for(XWPFParagraphp:doc.getParagraphs()){ListXWPFRunrunsp.getRuns();if(runs.isEmpty())continue;Stringtextp.getText();if(textnull||!text.contains(${))continue;// 簡單策略將整段文本一次性替換要求占位符不被 Run 拆分for(Map.EntryString,Stringe:params.entrySet()){Stringph${e.getKey()};if(text.contains(ph)){texttext.replace(ph,e.getValue()null?:e.getValue());}}// 寫回第一個 Run清空其余 Run避免殘留格式runs.get(0).setText(text,0);for(intiruns.size()-1;i0;i--){p.removeRun(i);}}}運行后將在 target 目錄生成體檢報告_張三.docx。三 核心能力實現(xiàn)動態(tài)表格體檢項目明細模板中預留一個表格約定第一行是表頭第二行是“數(shù)據(jù)模板行”POI 會復用該行樣式創(chuàng)建新行。// 體檢項目明細staticclassItem{Stringproject;Stringresult;Stringunit;StringrefLow;StringrefHigh;Stringconclusion;}publicstaticvoidfillTable(XWPFDocumentdoc,ListItemitems){ListXWPFTabletablesdoc.getTables();if(tables.isEmpty())return;XWPFTabletabletables.get(0);// 取第一個表格// 約定第2行為模板行索引1從它之后插入數(shù)據(jù)行XWPFTableRowtpltable.getRow(1);for(inti0;iitems.size();i){XWPFTableRowrowtable.insertNewTableRowAfter(tpl);// 復制模板行的單元格樣式淺拷貝POI 默認行為for(intc0;ctpl.getTableCells().size();c){XWPFTableCellsrctpl.getCell(c);XWPFTableCelldstrow.getCell(c);if(dstnull)dstrow.addNewTableCell();// 簡單文本填充如需保留樣式可深拷貝 CTRdst.setText(getCellText(items.get(i),c));}}// 可選移除模板行table.removeRow(1);}privatestaticStringgetCellText(Itemit,intcol){returnswitch(col){case0-it.project;case1-it.result;case2-it.unit;case3-it.refLow;case4-it.refHigh;case5-it.conclusion;default-;};}圖片插入體檢影像、簽名等使用 POI 的 addPicture尺寸以EMU為單位1 英寸 914400EMU。publicstaticvoidinsertImage(XWPFDocumentdoc,StringimgPath,intwidthInch,intheightInch)throwsException{try(FileInputStreamisnewFileInputStream(imgPath)){// 添加圖片數(shù)據(jù)并返回索引可選intidxdoc.addPictureData(is,XWPFDocument.PICTURE_TYPE_PNG);XWPFParagraphpdoc.createParagraph();XWPFRunrunp.createRun();run.addPicture(is,XWPFDocument.PICTURE_TYPE_PNG,imgPath,Units.toEMU(widthInch*914400),Units.toEMU(heightInch*914400));}}表格樣式與對齊居中、寬度通過底層CTTbl/ CTTblPr/ CTJc設置表格居中與寬度單位DXA常用全寬約9000。importstaticorg.openxmlformats.schemas.wordprocessingml.x2006.main.STJc.*;publicstaticvoidsetTableStyle(XWPFTabletable){CTTblPrtblPrtable.getCTTbl().addNewTblPr();CTJcjctblPr.addNewJc();jc.setVal(STJc.CENTER);CTTblWidthwidthtblPr.addNewTblW();width.setW(BigInteger.valueOf(9000));width.setType(STTblWidth.DXA);}模板占位符被 Run 拆分的處理現(xiàn)象占位符被 Word 樣式拆到多個XWPFRun導致簡單替換失效。解決思路在 Word 中將占位符粘貼為“無格式文本”保證整體位于同一 Run或在代碼中合并被拆分的 Run再替換遍歷 Run定位${與}合并中間 Run 的文本后再替換。四 模板規(guī)范與最佳實踐模板規(guī)范使用.docx所有占位符統(tǒng)一為${key}避免特殊字符與 XML 沖突。表格循環(huán)預留“表頭 模板行”模板行用于復制生成數(shù)據(jù)行。圖片占位預留位置段落或在代碼中指定插入點。樣式與編號盡量用 Word 樣式標題、正文、表格樣式避免手工格式影響復用。運行與資源模板放置于classpath使用ClassPathResource讀取便于 JAR 包部署。所有流使用 try-with-resources 關(guān)閉避免文件句柄泄漏。性能與穩(wěn)定性大數(shù)據(jù)量1萬行建議分頁生成多個文檔或?qū)С鯟SV/Excel附件。圖片壓縮后再寫入避免體積過大??删S護性將“文本替換、表格填充、圖片插入”封裝為獨立組件便于單元測試與復用。五 導出 PDF 與 HTTP 下載LibreOffice 轉(zhuǎn)換跨平臺、穩(wěn)定publicstaticbooleanconvertDocxToPdf(StringinDocx,StringoutDir){StringosSystem.getProperty(os.name).toLowerCase();Stringcmd;if(os.contains(win)){cmdcmd /c start /wait soffice --headless --invisible --convert-to pdf:writer_pdf_Export inDocx --outdir outDir;}else{cmdlibreoffice --headless --invisible --convert-to pdf:writer_pdf_Export inDocx --outdir outDir;}try{ProcesspRuntime.getRuntime().exec(cmd);intexitp.waitFor();returnexit0;}catch(Exceptione){e.printStackTrace();returnfalse;}}Spring Boot 下載接口示例GetMapping(/report/export)publicvoidexport(HttpServletResponseresp)throwsException{// 1) 生成 .docxStringdocxtarget/體檢報告_張三.docx;// 生成邏輯// 2) 轉(zhuǎn) PDFStringpdfdocx.replace(.docx,.pdf);convertDocxToPdf(docx,target);// 3) 輸出 PDFresp.setContentType(application/pdf);resp.setHeader(Content-Disposition,attachment;filenameURLEncoder.encode(體檢報告.pdf,UTF-8));Files.copy(Paths.get(pdf),resp.getOutputStream());resp.getOutputStream().flush();}提示服務器需安裝LibreOfficeWindows 下建議使用安裝路徑下的 soffice.exe。轉(zhuǎn)換是外部進程注意超時與異常捕獲。六 常見問題與排查清單占位符未被替換檢查占位符是否被樣式拆分到多個XWPFRun統(tǒng)一為無格式文本或合并 Run 后再替換。生成后 Word 損壞避免并發(fā)寫同一文檔確保所有流關(guān)閉POI 版本升級到穩(wěn)定版≥5.2.3。圖片不顯示或變形尺寸單位使用EMU確認圖片格式與 addPicture 類型一致必要時壓縮圖片。表格樣式丟失通過復制模板行樣式或操作底層CTTc/CTP保留格式必要時設置表格居中與寬度。Linux 轉(zhuǎn) PDF 失敗檢查 LibreOffice 是否安裝、命令路徑、權(quán)限與可用字體查看進程退出碼與日志。七 一鍵運行與擴展建議一鍵運行步驟準備模板resources/templates/health_report_template.docx含name、{name}、name、{gender}、age、{age}、age、{examDate} 與“項目明細”表格。運行單元測試或直接執(zhí)行 main 方法生成.docx與.pdf。打開 PDF 校驗排版、表格、圖片與編碼中文。擴展建議模板引擎化將模板標簽升級為##{foreachRows}##、##{foreachTable}##等實現(xiàn)表格行/表格級循環(huán)與更靈活的布局。頁眉頁腳與頁碼操作XWPFHeaderFooter與底層CTP添加頁碼域。電子簽名/二維碼生成圖片后插入頁腳或指定區(qū)域。多格式導出同時支持.docx/.pdf大數(shù)據(jù)量導出Excel匯總。異步與緩存報告生成放入異步任務生成后緩存 PDF避免重復渲染。附 模板占位符與表格示例文本占位符示例姓名${name}性別${gender}年齡${age}體檢日期${examDate}表格示例項目明細項目結(jié)果單位參考低參考高結(jié)論身高175cm體重68kg收縮壓118mmHg90120正常舒張壓76mmHg6080正常將以上表格的第二行作為“模板行”程序會復制該行生成數(shù)據(jù)行最終移除模板行。參考要點使用Apache POI XWPF操作.docx模板完成文本替換、表格行循環(huán)與圖片插入模板占位符需位于同一XWPFRun內(nèi)避免替換失敗。通過LibreOffice headless將.docx轉(zhuǎn)換為.pdf適合服務器批量導出與歸檔。圖片插入需使用EMU單位設置寬高表格可通過底層CTTbl/CTJc設置居中與全寬保證打印版式穩(wěn)定。