1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > Freemark 模板生成doc文件 xml doc文件转docx 文件 docx文件转pdf文件

Freemark 模板生成doc文件 xml doc文件转docx 文件 docx文件转pdf文件

时间:2022-06-09 05:41:38

相关推荐

Freemark 模板生成doc文件 xml doc文件转docx 文件 docx文件转pdf文件

freemark 模板生成doc文件,此doc文件为xml格式,无法直接转pdf

需要doc转docx文件,才能转pdf

方法1:docx4j 转 pdf

方法2:e-iceblue docx 转 pdf、xml-doc 转 pdf

打包方式,需要本地引入jar包,下载后,将lib里的jar包放入项目中

Free Spire.Doc for Java | 100% 免费 Java Word 组件

pom文件引入${project.basedir} 是系统变量,代表本目录,build配置是打包时,将本地文件加入项目

<dependency><groupId>e-iceblue</groupId><artifactId>spire.pdf</artifactId><version>5.2.0</version><scope>system</scope><systemPath>${project.basedir}/src/main/resources/lib/Spire.Doc.jar</systemPath></dependency><build><finalName>${project.artifactId}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><includeSystemScope>true</includeSystemScope></configuration></plugin></plugins></build>

​​​​​​​

方法3:poi (可以自己搜教程)

依赖

<!-- iText pdf 依赖--><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13</version></dependency><dependency><groupId>org.xhtmlrenderer</groupId><artifactId>flying-saucer-pdf-itext5</artifactId><version>9.1.5</version></dependency><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.31</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version><scope>compile</scope></dependency><!-- docx 依赖 导出pdf --><dependency><groupId>org.docx4j</groupId><artifactId>docx4j</artifactId><version>6.1.2</version><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.docx4j</groupId><artifactId>docx4j-export-fo</artifactId><version>6.0.0</version></dependency><!-- e-iceblue 导出pdf --><dependency><groupId>e-iceblue</groupId><artifactId>spire.doc.free</artifactId><version>5.2.0</version></dependency><repositories><repository><id>public</id><name>阿里云公共仓库</name><url>/repository/public/</url><releases><enabled>true</enabled></releases></repository><repository><id>com.e-iceblue</id><url>https://repo.e-/repository/maven-public/</url></repository></repositories>

/*** @Author: LiSaiHang* @Date: /4/23 3:26 下午*/@RestController@RequestMapping("/module/documents")@Slf4jpublic class FreeMarkController {@GetMapping("/generate")public void doc(HttpServletResponse response) {Map<String, Object> dataMap = new HashMap<>();///姓名dataMap.put("name", "张三");dataMap.put("phone", "15532123328");dataMap.put("idCard", "130429199711113617");dataMap.put("sex", "男");String result = "";String docName = System.currentTimeMillis() + (int) (Math.random() * 90000 + 10000) + ".doc";String pdfName = System.currentTimeMillis() + (int) (Math.random() * 90000 + 10000) + ".pdf";response.setHeader("content-Type", "application/octet-stream");response.setCharacterEncoding("utf-8");response.setHeader("Content-disposition", "attachment;filename=" + pdfName);// 下载输出流ServletOutputStream outputStream = null;// doc文件输出流InputStream inputStream = null;// pdf文件输出流ByteArrayOutputStream fileOutputStream = null;try {// 获取渲染数据result = FreeMarkUtils.freemarkerRender(dataMap, "test.doc");inputStream = new ByteArrayInputStream(result.getBytes(StandardCharsets.UTF_8));// 生成 doc 文件FileUtils.copyInputStreamToFile(inputStream, new File(docName));// doc 文件转docx文件final String docxFile = this.docToDocx(docName);// 方法1:docx文件转pdf文件// this.docx4jWordToPdf(docxFile, pdfName);// 方法2:docx文件转pdf文件// com.spire.doc.Document 实例化Document类的对象Document doc = new Document();// 加载Worddoc.loadFromFile(docxFile);// 保存为PDF格式 com.spire.doc.FileFormatdoc.saveToFile(pdfName, FileFormat.PDF);// pdf 缩放设置pdfPageSetting(pdfName);// 获取文件输出流fileOutputStream = FreeMarkUtils.getFileOutputStream(new File(pdfName));// 设置文件名outputStream = response.getOutputStream();outputStream.write(fileOutputStream.toByteArray());} catch (Exception e) {e.printStackTrace();} finally {try {if (outputStream != null) {outputStream.close();}if (fileOutputStream != null) {fileOutputStream.close();}if (inputStream != null) {inputStream.close();}} catch (IOException e) {e.printStackTrace();}}}/*** doc转docx* @param docPath doc文件路径* @return*/private String docToDocx(String docPath) {String docxPath = docPath.replaceAll("(\\.docx)|(\\.doc)", ".docx");try (FileInputStream inputStream = new FileInputStream(docPath);) {WordprocessingMLPackage wmlPackage = Docx4J.load(inputStream);//转换为DOCXtry (FileOutputStream docx = new FileOutputStream(docxPath);) {Docx4J.save(wmlPackage, docx, Docx4J.FLAG_SAVE_ZIP_FILE);docPath = docxPath;}} catch (Exception e) {System.out.println((docPath + ":不需要转换:" + e.getLocalizedMessage()));}return docPath;}/*** 通过docx4j 实现word转pdf** @param sourcePath 源文件地址 如 /root/example.doc* @param targetPath 目标文件地址 如 /root/example.pdf*/public String docx4jWordToPdf(String sourcePath, String targetPath) {try {WordprocessingMLPackage pkg = Docx4J.load(new File(sourcePath));Mapper fontMapper = new IdentityPlusMapper();fontMapper.put("隶书", PhysicalFonts.get("LiSu"));fontMapper.put("宋体", PhysicalFonts.get("SimSun"));fontMapper.put("微软雅黑", PhysicalFonts.get("Microsoft Yahei"));fontMapper.put("黑体", PhysicalFonts.get("SimHei"));fontMapper.put("楷体", PhysicalFonts.get("KaiTi"));fontMapper.put("新宋体", PhysicalFonts.get("NSimSun"));fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));fontMapper.put("华文仿宋", PhysicalFonts.get("STFangsong"));fontMapper.put("仿宋", PhysicalFonts.get("FangSong"));fontMapper.put("幼圆", PhysicalFonts.get("YouYuan"));fontMapper.put("华文宋体", PhysicalFonts.get("STSong"));fontMapper.put("华文中宋", PhysicalFonts.get("STZhongsong"));fontMapper.put("等线", PhysicalFonts.get("SimSun"));fontMapper.put("等线 Light", PhysicalFonts.get("SimSun"));fontMapper.put("华文琥珀", PhysicalFonts.get("STHupo"));fontMapper.put("华文隶书", PhysicalFonts.get("STLiti"));fontMapper.put("华文新魏", PhysicalFonts.get("STXinwei"));fontMapper.put("华文彩云", PhysicalFonts.get("STCaiyun"));fontMapper.put("方正姚体", PhysicalFonts.get("FZYaoti"));fontMapper.put("方正舒体", PhysicalFonts.get("FZShuTi"));fontMapper.put("华文细黑", PhysicalFonts.get("STXihei"));fontMapper.put("宋体扩展", PhysicalFonts.get("simsun-extB"));fontMapper.put("仿宋_GB2312", PhysicalFonts.get("FangSong_GB2312"));fontMapper.put("新細明體", PhysicalFonts.get("SimSun"));PhysicalFonts.addPhysicalFonts("SimSun", WordUtils.class.getResource("/simsun.ttc"));pkg.setFontMapper(fontMapper);Docx4J.toPDF(pkg, new FileOutputStream(targetPath));} catch (Exception e) {log.error("[docx4j] word转pdf失败:{}", e.toString());}return targetPath;}/*** 对pdf页面设置,缩放比例设置* @param pdfName pdf文件名称*/private void pdfPageSetting(String pdfName) {//创建PdfDocument实例PdfDocument originalDoc = new PdfDocument();//加载PDF文件originalDoc.loadFromFile(pdfName);//创建一个新的PdfDocument实例PdfDocument newDoc = new PdfDocument();//遍历所有PDF 页面for (int i = 0; i < originalDoc.getPages().getCount(); i++) {PdfPageBase page = originalDoc.getPages().get(i);//设置新文档的页边距为10PdfMargins margins = new PdfMargins(10);//设置新文档的页面大小为A2PdfPageBase newPage = newDoc.getPages().add(PdfPageSize.A2, margins);//调整画布,设置内容也根据页面的大小进行缩放double wScale = (PdfPageSize.A2.getWidth() - 20) / PdfPageSize.A4.getWidth();double hScale = (PdfPageSize.A2.getHeight() - 20) / PdfPageSize.A4.getHeight();newPage.getCanvas().scaleTransform(wScale, hScale);//复制原文档的内容到新文档newPage.getCanvas().drawTemplate(page.createTemplate(), new Point2D.Float());}//保存PDFnewDoc.saveToFile(pdfName);}}

工具类

package com.mon.utils;import com.itextpdf.text.*;import com.itextpdf.text.Image;import com.itextpdf.text.pdf.*;import freemarker.template.Configuration;import freemarker.template.Template;import freemarker.template.TemplateExceptionHandler;import lombok.extern.slf4j.Slf4j;import mons.io.FileUtils;import org.springframework.core.io.DefaultResourceLoader;import org.ponent;import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;import org.springframework.ui.freemarker.SpringTemplateLoader;import org.xhtmlrenderer.pdf.ITextFontResolver;import org.xhtmlrenderer.pdf.ITextRenderer;import java.io.*;import java.util.Map;/*** @Description: pdf 导出工具类* @Author: LiSaiHang* @Date: /1/7 11:30 上午*/@Component@Slf4jpublic class FreeMarkUtils {private FreeMarkUtils() {}private volatile static Configuration configuration;static {if (configuration == null) {synchronized (FreeMarkUtils.class) {if (configuration == null) {configuration = new Configuration(Configuration.VERSION_2_3_28);}}}}/*** freemarker 引擎渲染 html** @param dataMap 传入 html 模板的 Map 数据* @param fileName 模板文件名称* eg: "templates/template.ftl"* @return*/public static String freemarkerRender(Map<String, Object> dataMap, String fileName) {configuration.setDefaultEncoding("UTF-8");configuration.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);try {// TODO Jar包运行时,是无法读取classpath下资源文件,可以通过 SpringTemplateLoader 读取资源文件目录// 本地运行时,可以通过本地文件流读取资源文件final SpringTemplateLoader templateLoader = new SpringTemplateLoader(new DefaultResourceLoader(), "classpath:templates");configuration.setTemplateLoader(templateLoader);// 服务器运行时,可以通过目录,获取文件流读取资源文件// configuration.setDirectoryForTemplateLoading(new File("/Users/lisaihang/Documents/"));configuration.setLogTemplateExceptions(false);configuration.setWrapUncheckedExceptions(true);Template template = configuration.getTemplate(fileName);log.info("填充模板动态数据");return FreeMarkerTemplateUtils.processTemplateIntoString(template, dataMap);} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}return null;}/*** 使用 iText 生成 PDF 文档** @param htmlTmpStr html 模板文件字符串* @param fontFile 所需字体文件(相对路径+文件名)*/public static byte[] createHtml2Pdf(String htmlTmpStr, String fontFile) {log.info("根据模板生成PDF文件");ByteArrayOutputStream outputStream = null;byte[] result = null;// 生成 字体临时文件// TODO jar包运行后,是无法直接读取 classpath 下的资源文件,需要通过文件流读取,生成临时文件final String tempFont = "simsun_temp_"+ ".ttc";File existFile = new File(tempFont);if (!existFile.exists()) {final File tempFile = getTempFile(fontFile, tempFont);existFile = tempFile;}// TODO jar包运行后,是无法直接读取 classpath 下的资源文件,需要通过文件流读取,生成临时文件try {outputStream = new ByteArrayOutputStream();ITextRenderer renderer = new ITextRenderer();renderer.setDocumentFromString(htmlTmpStr);ITextFontResolver fontResolver = renderer.getFontResolver();// 解决中文支持问题,需要所需字体(ttc)文件fontResolver.addFont(existFile.getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);renderer.layout();renderer.createPDF(outputStream);// 对Html2Pdf 的文件插入水印图片final String fileName = System.currentTimeMillis() + (int) (Math.random() * 90000 + 10000) + ".pdf";addWaterMark(outputStream.toByteArray(), fileName);final ByteArrayOutputStream fileOutputStream = getFileOutputStream(new File(fileName));result = fileOutputStream.toByteArray();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (DocumentException e) {e.printStackTrace();} finally {try {if (outputStream != null) {outputStream.flush();outputStream.close();}//if (tempFile.exists()) {//tempFile.delete();//}} catch (IOException e) {e.printStackTrace();}}return result;}/*** 文件转字节输出流** @param outFile 文件* @return*/public static ByteArrayOutputStream getFileOutputStream(File outFile) {// 获取生成临时文件的输出流InputStream input = null;ByteArrayOutputStream bytestream = null;try {input = new FileInputStream(outFile);bytestream = new ByteArrayOutputStream();int ch;while ((ch = input.read()) != -1) {bytestream.write(ch);}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {input.close();bytestream.close();log.info("删除临时文件");if (outFile.exists()) {outFile.delete();}} catch (IOException e) {e.printStackTrace();}}return bytestream;}/*** 获取资源文件的临时文件* 资源文件打jar包后,不能直接获取,需要通过流获取生成临时文件** @param fileName 文件路径 temp/temp.ftl* @return*/public static File getTempFile(String fileName, String tempFont) {final File tempFile = new File(tempFont);InputStream fontTempStream = null;try {fontTempStream = FreeMarkUtils.class.getClassLoader().getResourceAsStream(fileName);FileUtils.copyInputStreamToFile(fontTempStream, tempFile);} catch (Exception e) {e.printStackTrace();} finally {try {if (fontTempStream != null) {fontTempStream.close();}} catch (IOException e) {e.printStackTrace();}}return tempFile;}/*** 插入图片水印* @param srcByte 已生成PDF的字节数组(流转字节)* @param destFile 生成有水印的临时文件 temp.pdf* @return*/public static FileOutputStream addWaterMark(byte[] srcByte, String destFile) {// 待加水印的文件PdfReader reader = null;// 加完水印的文件PdfStamper stamper = null;FileOutputStream fileOutputStream = null;try {reader = new PdfReader(srcByte);fileOutputStream = new FileOutputStream(destFile);stamper = new PdfStamper(reader, fileOutputStream);int total = reader.getNumberOfPages() + 1;PdfContentByte content;// 设置字体//BaseFont font = BaseFont.createFont();// 循环对每页插入水印for (int i = 1; i < total; i++) {final PdfGState gs = new PdfGState();// 水印的起始content = stamper.getUnderContent(i);// 开始content.beginText();// 设置颜色 默认为蓝色//content.setColorFill(BaseColor.BLUE);// content.setColorFill(Color.GRAY);// 设置字体及字号//content.setFontAndSize(font, 38);// 设置起始位置// content.setTextMatrix(400, 880);//content.setTextMatrix(textWidth, textHeight);// 开始写入水印//content.showTextAligned(Element.ALIGN_LEFT, text, textWidth, textHeight, 45);// 设置水印透明度// 设置笔触字体不透明度为0.4fgs.setStrokeOpacity(0f);Image image = null;image = Image.getInstance("https://dpxdata.oss-cn-/upload/kbt/null_1660715685801.png");// 设置坐标 绝对位置 X Yimage.setAbsolutePosition(472, 785);// 设置旋转弧度image.setRotation(0);// 旋转 弧度// 设置旋转角度image.setRotationDegrees(0);// 旋转 角度// 设置等比缩放image.scalePercent(4);// 依照比例缩放// image.scaleAbsolute(200,100);//自定义大小// 设置透明度content.setGState(gs);// 添加水印图片content.addImage(image);// 设置透明度content.setGState(gs);//结束设置content.endText();content.stroke();}} catch (IOException e) {e.printStackTrace();} catch (DocumentException e) {e.printStackTrace();} finally {try {stamper.close();fileOutputStream.close();reader.close();} catch (DocumentException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}return fileOutputStream;}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。