通过FreeMarker生成word文档docx转pdf(二)
docx属于zip的一种,这里只需要操作word/document.xml中的数据
1、新建detection.docx文件,用winrar打开文件,取出word/document.xml,进行freeMarker语句替换。
替换xml文件w:body中传入值为freeMarker语句,更改为detection.xml,
<w:body> <w:p w14:paraId="59211CB6" w14:textId="2234D275" w:rsidR="00C76028" w:rsidRDefault="00C76028" w:rsidP="00C76028"> <w:pPr> <w:pStyle w:val="1"/> <w:keepNext w:val="0"/> <w:keepLines w:val="0"/> <w:jc w:val="center"/> </w:pPr> <w:r> <w:rPr> <w:rFonts w:hint="eastAsia"/> </w:rPr> <w:t>四性检测报告(${link})</w:t> </w:r> </w:p> <w:tbl> <w:tblPr> <w:tblStyle w:val="a3"/> <w:tblW w:w="8532" w:type="dxa"/> <w:tblLook w:val="04A0" w:firstRow="1" w:lastRow="0" w:firstColumn="1" w:lastColumn="0" w:noHBand="0" w:noVBand="1"/> </w:tblPr> <w:tblGrid> <w:gridCol w:w="1129"/> <w:gridCol w:w="1756"/> <w:gridCol w:w="1079"/> <w:gridCol w:w="154"/> <w:gridCol w:w="1264"/> <w:gridCol w:w="163"/> <w:gridCol w:w="825"/> <w:gridCol w:w="570"/> <w:gridCol w:w="599"/> <w:gridCol w:w="993"/> </w:tblGrid> <w:tr w:rsidR="00C76028" w14:paraId="544E66C0" w14:textId="77777777" w:rsidTr="002C287D"> <w:trPr> <w:trHeight w:val="549"/> </w:trPr> <w:tc> <w:tcPr> <w:tcW w:w="1129" w:type="dxa"/> </w:tcPr> <w:p w14:paraId="66574DC1" w14:textId="77777777" w:rsidR="00C76028" w:rsidRPr="00AF1AEA" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> <w:rPr> <w:b/> <w:bCs/> </w:rPr> </w:pPr> <w:r w:rsidRPr="00AF1AEA"> <w:rPr> <w:rFonts w:hint="eastAsia"/> <w:b/> <w:bCs/> </w:rPr> <w:t>检验编号</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1756" w:type="dxa"/> </w:tcPr> <w:p w14:paraId="3E4EC493" w14:textId="2475519D" w:rsidR="00C76028" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> </w:pPr> <w:proofErr w:type="spellStart"/> <w:r w:rsidRPr="00C76028"> <w:t>${inNumber}</w:t> </w:r> <w:proofErr w:type="spellEnd"/> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1079" w:type="dxa"/> </w:tcPr> <w:p w14:paraId="6ED7FE9C" w14:textId="77777777" w:rsidR="00C76028" w:rsidRPr="00AF1AEA" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> <w:rPr> <w:b/> <w:bCs/> </w:rPr> </w:pPr> <w:r w:rsidRPr="00AF1AEA"> <w:rPr> <w:rFonts w:hint="eastAsia"/> <w:b/> <w:bCs/> </w:rPr> <w:t>检验时间</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1581" w:type="dxa"/> <w:gridSpan w:val="3"/> </w:tcPr> <w:p w14:paraId="6F4FA440" w14:textId="055BCC6B" w:rsidR="00C76028" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> </w:pPr> <w:proofErr w:type="spellStart"/> <w:r w:rsidRPr="00C76028"> <w:t>${inTime}</w:t> </w:r> <w:proofErr w:type="spellEnd"/> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1395" w:type="dxa"/> <w:gridSpan w:val="2"/> </w:tcPr> <w:p w14:paraId="5D5D1592" w14:textId="77777777" w:rsidR="00C76028" w:rsidRPr="00AF1AEA" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> <w:rPr> <w:b/> <w:bCs/> </w:rPr> </w:pPr> <w:r w:rsidRPr="00AF1AEA"> <w:rPr> <w:rFonts w:hint="eastAsia"/> <w:b/> <w:bCs/> </w:rPr> <w:t>检验人</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1592" w:type="dxa"/> <w:gridSpan w:val="2"/> </w:tcPr> <w:p w14:paraId="571178A6" w14:textId="4099E11C" w:rsidR="00C76028" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> </w:pPr> <w:proofErr w:type="spellStart"/> <w:r w:rsidRPr="00C76028"> <w:t>${createName}</w:t> </w:r> <w:proofErr w:type="spellEnd"/> </w:p> </w:tc> </w:tr> <w:tr w:rsidR="00C76028" w14:paraId="110D174C" w14:textId="77777777" w:rsidTr="002C287D"> <w:trPr> <w:trHeight w:val="487"/> </w:trPr> <w:tc> <w:tcPr> <w:tcW w:w="1129" w:type="dxa"/> </w:tcPr> <w:p w14:paraId="5EC8A38C" w14:textId="77777777" w:rsidR="00C76028" w:rsidRPr="00AF1AEA" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> <w:rPr> <w:b/> <w:bCs/> </w:rPr> </w:pPr> <w:r w:rsidRPr="00AF1AEA"> <w:rPr> <w:rFonts w:hint="eastAsia"/> <w:b/> <w:bCs/> </w:rPr> <w:t>检验总数</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1756" w:type="dxa"/> </w:tcPr> <w:p w14:paraId="52371CDB" w14:textId="43C8B1DA" w:rsidR="00C76028" w:rsidRPr="00975BA5" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> </w:pPr> <w:proofErr w:type="spellStart"/> <w:r w:rsidRPr="00C76028"> <w:t>${inTotal}</w:t> </w:r> <w:proofErr w:type="spellEnd"/> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1079" w:type="dxa"/> </w:tcPr> <w:p w14:paraId="275AE616" w14:textId="77777777" w:rsidR="00C76028" w:rsidRPr="00AF1AEA" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> <w:rPr> <w:b/> <w:bCs/> </w:rPr> </w:pPr> <w:r w:rsidRPr="00AF1AEA"> <w:rPr> <w:rFonts w:hint="eastAsia"/> <w:b/> <w:bCs/> </w:rPr> <w:t>通过数</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1581" w:type="dxa"/> <w:gridSpan w:val="3"/> </w:tcPr> <w:p w14:paraId="65399C60" w14:textId="1BC347B2" w:rsidR="00C76028" w:rsidRPr="00975BA5" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> </w:pPr> <w:proofErr w:type="spellStart"/> <w:r w:rsidRPr="00C76028"> <w:t>${passTotal}</w:t> </w:r> <w:proofErr w:type="spellEnd"/> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1395" w:type="dxa"/> <w:gridSpan w:val="2"/> </w:tcPr> <w:p w14:paraId="6E310C87" w14:textId="77777777" w:rsidR="00C76028" w:rsidRPr="00AF1AEA" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> <w:rPr> <w:b/> <w:bCs/> </w:rPr> </w:pPr> <w:r w:rsidRPr="00AF1AEA"> <w:rPr> <w:rFonts w:hint="eastAsia"/> <w:b/> <w:bCs/> </w:rPr> <w:t>未通过数</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1592" w:type="dxa"/> <w:gridSpan w:val="2"/> </w:tcPr> <w:p w14:paraId="6ABA8855" w14:textId="18CEF9D0" w:rsidR="00C76028" w:rsidRPr="00975BA5" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> </w:pPr> <w:proofErr w:type="spellStart"/> <w:r w:rsidRPr="00C76028"> <w:t>${nopassTotal}</w:t> </w:r> <w:proofErr w:type="spellEnd"/> </w:p> </w:tc> </w:tr> <w:tr w:rsidR="00C76028" w14:paraId="3E960F7B" w14:textId="77777777" w:rsidTr="00C76028"> <w:trPr> <w:trHeight w:val="706"/> </w:trPr> <w:tc> <w:tcPr> <w:tcW w:w="8532" w:type="dxa"/> <w:gridSpan w:val="10"/> </w:tcPr> <w:p w14:paraId="3E438019" w14:textId="77777777" w:rsidR="00C76028" w:rsidRPr="00AF1AEA" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:pStyle w:val="4"/> <w:keepNext w:val="0"/> <w:keepLines w:val="0"/> <w:spacing w:line="377" w:lineRule="auto"/> <w:jc w:val="center"/> </w:pPr> <w:r w:rsidRPr="00AF1AEA"> <w:rPr> <w:rFonts w:hint="eastAsia"/> </w:rPr> <w:t>检测概述</w:t> </w:r> </w:p> </w:tc> </w:tr> <w:tr w:rsidR="00C76028" w14:paraId="2B20A3D5" w14:textId="77777777" w:rsidTr="00C76028"> <w:trPr> <w:trHeight w:val="499"/> </w:trPr> <w:tc> <w:tcPr> <w:tcW w:w="4118" w:type="dxa"/> <w:gridSpan w:val="4"/> </w:tcPr> <w:p w14:paraId="1DDCB7B4" w14:textId="77777777" w:rsidR="00C76028" w:rsidRPr="00AF1AEA" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> <w:rPr> <w:b/> <w:bCs/> </w:rPr> </w:pPr> <w:r w:rsidRPr="00AF1AEA"> <w:rPr> <w:rFonts w:hint="eastAsia"/> <w:b/> <w:bCs/> </w:rPr> <w:t>档号</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1264" w:type="dxa"/> </w:tcPr> <w:p w14:paraId="37803BF3" w14:textId="77777777" w:rsidR="00C76028" w:rsidRPr="00AF1AEA" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> <w:rPr> <w:b/> <w:bCs/> </w:rPr> </w:pPr> <w:r w:rsidRPr="00AF1AEA"> <w:rPr> <w:rFonts w:hint="eastAsia"/> <w:b/> <w:bCs/> </w:rPr> <w:t>真实性</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="988" w:type="dxa"/> <w:gridSpan w:val="2"/> </w:tcPr> <w:p w14:paraId="4D889EA9" w14:textId="77777777" w:rsidR="00C76028" w:rsidRPr="00AF1AEA" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> <w:rPr> <w:b/> <w:bCs/> </w:rPr> </w:pPr> <w:r w:rsidRPr="00AF1AEA"> <w:rPr> <w:rFonts w:hint="eastAsia"/> <w:b/> <w:bCs/> </w:rPr> <w:t>完整性</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1169" w:type="dxa"/> <w:gridSpan w:val="2"/> </w:tcPr> <w:p w14:paraId="0D3B9AE1" w14:textId="77777777" w:rsidR="00C76028" w:rsidRPr="00AF1AEA" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> <w:rPr> <w:b/> <w:bCs/> </w:rPr> </w:pPr> <w:r w:rsidRPr="00975BA5"> <w:rPr> <w:rFonts w:hint="eastAsia"/> <w:b/> <w:bCs/> </w:rPr> <w:t>可用性</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="993" w:type="dxa"/> </w:tcPr> <w:p w14:paraId="42B16947" w14:textId="77777777" w:rsidR="00C76028" w:rsidRPr="00975BA5" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> <w:rPr> <w:b/> <w:bCs/> </w:rPr> </w:pPr> <w:r w:rsidRPr="00975BA5"> <w:rPr> <w:rFonts w:hint="eastAsia"/> <w:b/> <w:bCs/> </w:rPr> <w:t>安全性</w:t> </w:r> </w:p> </w:tc> </w:tr> <#list summary as work> <w:tr w:rsidR="00C76028" w14:paraId="2D9C8C8A" w14:textId="77777777" w:rsidTr="00C76028"> <w:trPr> <w:trHeight w:val="499"/> </w:trPr> <w:tc> <w:tcPr> <w:tcW w:w="4118" w:type="dxa"/> <w:gridSpan w:val="4"/> </w:tcPr> <w:p w14:paraId="1E39F075" w14:textId="0559CDD4" w:rsidR="00C76028" w:rsidRPr="00A15B12" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> </w:pPr> <w:r w:rsidRPr="00C76028"> <w:t>${work.DH}</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1264" w:type="dxa"/> </w:tcPr> <w:p w14:paraId="2FCA7652" w14:textId="19867DC6" w:rsidR="00C76028" w:rsidRPr="00A15B12" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> </w:pPr> <w:r w:rsidRPr="00C76028"> <w:t>${work.authenticity}</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="988" w:type="dxa"/> <w:gridSpan w:val="2"/> </w:tcPr> <w:p w14:paraId="0529FC03" w14:textId="58C8F1D1" w:rsidR="00C76028" w:rsidRPr="00A15B12" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> </w:pPr> <w:r w:rsidRPr="00C76028"> <w:t>${work.integrity}</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1169" w:type="dxa"/> <w:gridSpan w:val="2"/> </w:tcPr> <w:p w14:paraId="36B5B8DC" w14:textId="416A9A40" w:rsidR="00C76028" w:rsidRPr="00A15B12" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> </w:pPr> <w:r w:rsidRPr="00C76028"> <w:t>${work.availability}</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="993" w:type="dxa"/> </w:tcPr> <w:p w14:paraId="7481AB7B" w14:textId="17CDE97C" w:rsidR="00C76028" w:rsidRPr="00A15B12" w:rsidRDefault="00C76028" w:rsidP="005E6CB1"> <w:pPr> <w:spacing w:line="480" w:lineRule="auto"/> <w:jc w:val="center"/> </w:pPr> <w:r w:rsidRPr="00C76028"> <w:t>${work.security}</w:t> </w:r> </w:p> </w:tc> </w:tr> </#list> </w:tbl> <w:p w14:paraId="419AD697" w14:textId="77777777" w:rsidR="00962D4E" w:rsidRDefault="00962D4E" w:rsidP="00C76028"/> <w:sectPr w:rsidR="00962D4E"> <w:pgSz w:w="11906" w:h="16838"/> <w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="851" w:footer="992" w:gutter="0"/> <w:cols w:space="425"/> <w:docGrid w:type="lines" w:linePitch="312"/> </w:sectPr> </w:body>
yml配置文件
testReport:
# 检测报告配置文件地址
templatePath: /home/dagl/work/template
# 模板docx文件地址
detectionFilePath: /home/dagl/work/template/detection.docx
# 检测报告概述配置文件名称
detectionFileName: detection.xml
# 生成报告地址
generatePath: /home/dagl/work
# 字体文件配置
windowsFont: C:\\WINDOWS\\Fonts\\SIMYOU.TTF
linuxFont: /usr/share/fonts/chinese/simheittf.ttf
pom文的maven
<dependency> <groupId>com.lowagie</groupId> <artifactId>itext</artifactId> <version>2.1.7</version> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.31</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>ooxml-schemas</artifactId> <version>1.3</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.15</version> </dependency> <dependency> <groupId>fr.opensagres.xdocreport</groupId> <artifactId>org.apache.poi.xwpf.converter.pdf</artifactId> <version>1.0.6</version> <exclusions> <exclusion> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> </exclusion> <exclusion> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> </exclusion> <exclusion> <groupId>org.apache.poi</groupId> <artifactId>ooxml-schemas</artifactId> </exclusion> </exclusions> </dependency>
2、数据填充xml
@Service public class DetectionServiceImpl implements IDetectionService { /*模板文件地址*/ @Value("${testReport.templatePath}") private String templatePath; /*检测报告概述模板docx文件地址及名称*/ @Value("${testReport.detectionFilePath}") private String detectionFilePath; /*检测报告概述配置文件名称*/ @Value("${testReport.detectionFileName}") private String detectionFileName; /*生成文件地址*/ @Value("${testReport.generatePath}") private String generatePath; /*windows字体地址*/ @Value("${testReport.windowsFont}") private String windowsFont; /*linux字体地址*/ @Value("${testReport.linuxFont}") private String linuxFont; @Autowired private DetectionMapper detectionMapper; /** * 检擦报告概述 * @date 18:33 2021/12/24 * @param monitoringZongId 检测报告总表 * @return 文件地址 **/ @Override public String testReportSummary(String monitoringZongId){ Map<String,Object> map = new HashMap<>(); List<Map<String,String>> mapList = detectionMapper.selectMonitoringZong(monitoringZongId); /*判断文件是否存在,存在则直接返回地址*/ String inspectionNumber = mapList.get(0).get("inspectionNumber"); String generatePathNamePdf = generatePath + File.separator + inspectionNumber + File.separator + inspectionNumber + ".pdf"; File file = new File(generatePathNamePdf); if(file.exists()){ return generatePathNamePdf; } List<Map<String,String>> mapListSummary = detectionMapper.selectMonitoringSummary(monitoringZongId, null); map.put("link", mapList.get(0).get("link")); map.put("inNumber", inspectionNumber); map.put("inTime", mapList.get(0).get("inspectionTime")); map.put("createName", mapList.get(0).get("createName")); map.put("inTotal", mapList.get(0).get("inspectionTotal")); map.put("passTotal", mapList.get(0).get("passTotal")); map.put("nopassTotal", mapList.get(0).get("nopassTotal")); List<Map<String,String>> listSummary = new ArrayList<>(); for (Map<String,String> map2 : mapListSummary){ Map<String,String> map1 = new HashMap<>(); map1.put("DH", map2.get("dh")); map1.put("authenticity", map2.get("authenticity")); map1.put("security", map2.get("security")); map1.put("integrity", map2.get("integrity")); map1.put("availability", map2.get("availability")); listSummary.add(map1); } map.put("summary", listSummary); try { /*生成doc文件方法*/ /*DocumentHandler documentHandler = new DocumentHandler(); generatePathNamePdf = documentHandler.createDoc(map, detectionFilePath, detectionFileName, generatePath + File.separator + mapList.get(0).get("inspectionNumber"), mapList.get(0).get("inspectionNumber")); */ /*输出文档路径是否存在,不存在创建文件夹*/ File filePath = new File(generatePath + File.separator + mapList.get(0).get("inspectionNumber")); if (!filePath.exists()) { filePath.mkdir(); } /*生成docx文件xml文件*/ String xmlTemp = generatePath + File.separator + mapList.get(0).get("inspectionNumber") + File.separator + mapList.get(0).get("inspectionNumber") + ".xml"; /*生成docx文件*/ String toFilePath = generatePath + File.separator + mapList.get(0).get("inspectionNumber") + File.separator + mapList.get(0).get("inspectionNumber") + ".docx"; Writer out = new FileWriter(new File(xmlTemp)); XmlToExcel.process(detectionFileName, map, out, templatePath); XmlToDocx xtd = new XmlToDocx(); xtd.outDocx(new File(xmlTemp), detectionFilePath, toFilePath, generatePathNamePdf, windowsFont, linuxFont); } catch (Exception e) { e.printStackTrace(); File pathFile = new File(generatePathNamePdf); if (pathFile.exists()) { pathFile.delete(); } return null; } return generatePathNamePdf; } /** * 日期格式化 * * @return * @date 23:32 2021/12/12 **/ public String dateTool() { Date date = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); return simpleDateFormat.format(date); } }
import fr.opensagres.xdocreport.itext.extension.font.IFontProvider; import freemarker.template.TemplateException; import org.apache.poi.xwpf.converter.pdf.PdfConverter; import org.apache.poi.xwpf.converter.pdf.PdfOptions; import org.apache.poi.xwpf.usermodel.XWPFDocument; import com.lowagie.text.Font; import com.lowagie.text.pdf.BaseFont; import java.io.*; import java.nio.file.Files; import java.nio.file.Paths; import java.util.*; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; /** * @ClassName XmlToDocx * @author heGang * 其实docx属于zip的一种,这里只需要操作word/document.xml中的数据,其他的数据不用动 * 临时模板xml生成docx文件 * @date 1:17 2021/12/27 * @version 1.0 **/ public class XmlToDocx { /** * * @param documentFile 动态生成数据的docunment.xml文件 * @param docxTemplate docx的模板 * @param toFilePath 需要导出的文件路径 * @param generatePathNamePdf 导出pdf文件地址 * @throws ZipException * @throws IOException */ public void outDocx(File documentFile, String docxTemplate, String toFilePath, String generatePathNamePdf, String windowsFont, String linuxFont) throws ZipException, IOException { try { File docxFile = new File(docxTemplate); ZipFile zipFile = new ZipFile(docxFile); Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries(); ZipOutputStream zipout = new ZipOutputStream(new FileOutputStream(toFilePath)); int len = -1; byte[] buffer = new byte[1024]; while (zipEntrys.hasMoreElements()) { ZipEntry next = zipEntrys.nextElement(); InputStream is = zipFile.getInputStream(next); // 把输入流的文件传到输出流中 如果是word/document.xml由我们输入 zipout.putNextEntry(new ZipEntry(next.toString())); if ("word/document.xml".equals(next.toString())) { InputStream in = new FileInputStream(documentFile); while ((len = in.read(buffer)) != -1) { zipout.write(buffer, 0, len); } in.close(); } else { while ((len = is.read(buffer)) != -1) { zipout.write(buffer, 0, len); } is.close(); } } zipout.close(); } catch (Exception e) { e.printStackTrace(); } /*docx生成pdf*/ XWPFDocument document; try (InputStream doc = Files.newInputStream(Paths.get(toFilePath))) { document = new XWPFDocument(doc); } PdfOptions options = PdfOptions.create(); /*docx生成pdf设置字体,windows生成pdf时可以不需要以下内容,linux需要进行字体设置*/ options.fontProvider(new IFontProvider() { @Override public Font getFont(String familyName, String encoding, float size, int style, java.awt.Color color) { try { /*iTextAsian.jar*/ /*BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);*/ String prefixFont = null; String os = System.getProperties().getProperty("os.name"); if (os.startsWith("win") || os.startsWith("Win")) { /*windows字体*/ prefixFont = windowsFont; } else { /*linux字体*/ prefixFont = linuxFont; } BaseFont bfChinese = BaseFont.createFont(prefixFont, BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED); Font fontChinese = new Font(bfChinese, size, style, color); if (familyName != null) fontChinese.setFamily(familyName); return fontChinese; } catch (Exception e) { e.printStackTrace(); return null; } } }); /*生成pdf*/ try (OutputStream out = Files.newOutputStream(Paths.get(generatePathNamePdf))) { PdfConverter.getInstance().convert(document, out, options); out.close(); } } }
import com.lowagie.text.Font; import com.lowagie.text.pdf.BaseFont; import fr.opensagres.xdocreport.itext.extension.font.IFontProvider; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import freemarker.template.Version; import org.apache.poi.xwpf.converter.pdf.PdfConverter; import org.apache.poi.xwpf.converter.pdf.PdfOptions; import org.apache.poi.xwpf.usermodel.XWPFDocument; import java.io.*; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Map; /** * @ClassName XmlToExcel * freemker生成模板零时文件xml * @date 1:10 2021/12/27 * @version 1.0 **/ public class XmlToExcel { private static XmlToExcel tplm = null; private Configuration configuration = null; private XmlToExcel(String templatePath) { configuration = new Configuration(new Version("2.3.0")); try { // 注册tmlplate的load路径 // configuration.setClassForTemplateLoading(this.getClass(), "/template/"); configuration.setDirectoryForTemplateLoading(new File(templatePath)); configuration.setDefaultEncoding("utf-8"); } catch (Exception e) { } } private static Template getTemplate(String name, String templatePath) throws IOException { if (tplm == null) { tplm = new XmlToExcel(templatePath); } return tplm.configuration.getTemplate(name); } /** * * @param templatefile 模板文件 * @param param 需要填充的内容 * @param out 填充完成输出的文件 * @throws IOException * @throws TemplateException */ public static void process(String templatefile, Map param, Writer out, String templatePath) throws IOException, TemplateException { // 获取模板 Template template = XmlToExcel.getTemplate(templatefile, templatePath); template.setOutputEncoding("UTF-8"); // 合并数据 template.process(param, out); if (out != null) { out.close(); } } }
生成文件
注:如果linux找不到字体。查看linux是否安装了字体。
如果没有,可以把windows中的字体放到项目下,指定路径。或者安装字体
本文来自博客园,作者:曾经已是追忆,转载请注明原文链接:https://www.cnblogs.com/hehanhan/p/15735637.html
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器