word转pdf怎么保持格式字体_word转pdf保持图片高清

admin|
38
问题背景描述

我们在做项目的时候,可能会遇到这样的一个需求,根据业务数据,生成一份pdf文件,然后提供给用户下载查看。

生成pdf文件,可能会有很多种方式实现:

1.根据html模板,把数据填充到html模板,生成一份pdf文件2.根据pdf模板,把数据填充到pdf模板,生成一份pdf文件3.根据word模板,把数据填充到word模板,生成一份pdf文件

对比了这3种实现方式:

第1种实现方式,html的代码,会导致有些样式丢失,效果不好。(不太建议)

第2种实现方式,操作起来,很麻烦,需要编写大量的代码,最终的效果也不是很友好。(难度比较大,不太建议)

第3种实现方式,这种实现,是个人目前觉得比较好的一种方式,样式,实现也可以接受啦!!!

以上,仅代表个人观点,可能有不对的地方,别喷,或轻点喷!!!

那今天咋们着重的讨论一下第3种实现方式!!!^_^

word转pdf说明

目前,word转pdf,我们可以借助openoffice帮我们实现这个功能。

但凡,有个但是啦,毕竟你要借助openoffice,这毕竟是一个工具,那咋们就不得不部署运行这个程序,那这样得话,不得加重咋们后期服务器的部署和运维了嘛?

所以这里,咋们还是得想想看,有无其他简单的实现方式?

哈哈,那肯定是有的啦,我们可以通过纯代码的方式,实现word转pdf的功能!!!

下面看哥们操作喽!!!^_^

word转pdf实现word模板数据填充工具类public class WordTemplateUtils { private static Logger logger = LoggerFactory.getLogger(WordTemplateUtils.class); /* * 根据Word模板生成word文档 * @param uploadPath 文件夹路径 * @param writePath 生成word文件路径 * @param templatePath word模板路径 * @param contentMap 填充数据 */ public static boolean writeWordByTemplate(String uploadPath, String writePath, String templatePath, Map<String, Object> contentMap) throws Exception { //如果文件夹不存在,新建文件夹 File file = new File(uploadPath); //如果路径不存在,新建 if (!file.exists() && !file.isDirectory()) { file.mkdirs(); } boolean result = false; logger.info("---根据模板生成word文档"); XWPFDocument document = new XWPFDocument(new FileInputStream(templatePath)); if (document == null) { logger.error("---模板文件不存在,tempPath:{}", templatePath); return result; } InputStream is = null; FileOutputStream fos = null; try { fos = new FileOutputStream(writePath); WordTemplateUtils.changeText(document, contentMap); //生成新的word文档 document.write(fos); result = true; } catch (IOException e) { logger.error("---输出word文档失败,原因:{}", e.getMessage()); result = false; } finally { if (is != null) { is.close(); } if (fos != null) { fos.close(); } } return result; } /** * 替换段落文本 * * @param document docx解析对象 * @param textMap 需要替换的信息 *** */ private static void changeText(XWPFDocument document, Map<String, Object> textMap) { //获取段落 *** List<XWPFParagraph> paragraphs = document.getParagraphs(); for (XWPFParagraph paragraph : paragraphs) { //判断此段落时候需要进行替换 String text = paragraph.getText(); System.out.println(text); if (!text.equals("")) { List<XWPFRun> runs = paragraph.getRuns(); for (XWPFRun run : runs) { String textR = run.getText(0);//读取的模板段落 if (StringUtils.isEmpty(textR)) { continue; } String newTxetR = ""; //判断文本是否需要进行替换 // System.out.print(textR + ","); for (Map.Entry<String, Object> entry : textMap.entrySet()) { //匹配模板与替换值 格式${key} String key = entry.getKey(); Object value = entry.getValue(); if (textR.contains(key)) {// if (value instanceof String) { //文字替换 String inputText = value.toString(); if (inputText.contains("\n")) {//包含换行符 String[] lines = inputText.split("\n"); //newTxetR = textR.replace(key, lines[0]); run.setText(lines[0].trim(), 0); // set first line into XWPFRun for (int i = 1; i < lines.length; i++) { // add break and insert new text run.addBreak();//换行 run.addTab();//缩进 run.setText(lines[i].trim()); } } else { newTxetR = textR.replace(key, (String) value); //替换模板原来位置 if (!newTxetR.equals("")) { run.setText(newTxetR, 0); } } } else if (value instanceof Map) { //图片替换 newTxetR = textR.replace(key, ""); //替换模板原来位置 if (!newTxetR.equals("")) { run.setText(newTxetR, 0); } Map picMap = (Map) value; int width = Integer.parseInt(picMap.get("width").toString()); int height = Integer.parseInt(picMap.get("height").toString()); int picType = getPictureType(picMap.get("type").toString()); FileInputStream fis = (FileInputStream) picMap.get("content"); try { String blipId = document.addPictureData(fis, picType); int id = document.getNextPicNameNumber(picType); createPicture(id, blipId, width, height, run); } catch (Exception e) { e.printStackTrace(); } } } } } } } } /** * @param id * @param blipId * @param width 宽 * @param height 高 * //* @param paragraph 段落 */ private static void createPicture(int id, String blipId, int width, int height, XWPFRun xwpfRun) { final int EMU = 9525; width *= EMU; height *= EMU; CTInline inline = xwpfRun.getCTR().addNewDrawing().addNewInline(); //CTInline inline = paragraph.createRun().getCTR().addNewDrawing().addNewInline(); //在遍历run列表的时候,创建新的run有可能会导致报错 String picXml = "" + "<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">" + " <a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">" + " <pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">" + " <pic:nvPicPr>" + " <pic:cNvPr id="" + id + "" name="Generated"/>" + " <pic:cNvPicPr/>" + " </pic:nvPicPr>" + " <pic:blipFill>" + " <a:blip r:embed="" + blipId + "" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"/>" + " <a:stretch>" + " <a:fillRect/>" + " </a:stretch>" + " </pic:blipFill>" + " <pic:spPr>" + " <a:xfrm>" + " <a:off x="0" y="0"/>" + " <a:ext cx="" + width + "" cy="" + height + ""/>" + " </a:xfrm>" + " <a:prstGeom prst="rect">" + " <a:avLst/>" + " </a:prstGeom>" + " </pic:spPr>" + " </pic:pic>" + " </a:graphicData>" + "</a:graphic>"; inline.addNewGraphic().addNewGraphicData(); XmlToken xmlToken = null; try { xmlToken = XmlToken.Factory.parse(picXml); } catch (XmlException xe) { xe.printStackTrace(); } inline.set(xmlToken); inline.setDistT(0); inline.setDistB(0); inline.setDistL(0); inline.setDistR(0); CTPositiveSize2D extent = inline.addNewExtent(); extent.setCx(width); extent.setCy(height); CTNonVisualDrawingProps docPr = inline.addNewDocPr(); docPr.setId(id); docPr.setName("docx_img_ " + id); docPr.setDescr("docx Picture"); } /** * 根据图片类型,取得对应的图片类型代码 * * @param picType * @return int */ private static int getPictureType(String picType) { int res = XWPFDocument.PICTURE_TYPE_PICT; if (picType != null) { if (picType.equalsIgnoreCase("png")) { res = XWPFDocument.PICTURE_TYPE_PNG; } else if (picType.equalsIgnoreCase("dib")) { res = XWPFDocument.PICTURE_TYPE_DIB; } else if (picType.equalsIgnoreCase("emf")) { res = XWPFDocument.PICTURE_TYPE_EMF; } else if (picType.equalsIgnoreCase("jpg") || picType.equalsIgnoreCase("jpeg")) { res = XWPFDocument.PICTURE_TYPE_JPEG; } else if (picType.equalsIgnoreCase("wmf")) { res = XWPFDocument.PICTURE_TYPE_WMF; } } return res; } public static void main(String[] args) throws Exception { Map<String, Object> contentMap = new HashMap<String, Object>(); //组装文本参数 contentMap.put("demo1", "示例1"); contentMap.put("demo2", "示例2"); String fileName = "demo.docx"; WordTemplateUtils.writeWordByTemplate("D:\word\file", ""D:\word\file\" + fileName, "D:\word\template\template.docx", contentMap); }}复制代码

word模板,可以是这样:

最终生成的效果如下:

word转pdf工具类/** * Word或Excel 转Pdf 工具类 * * 备注:需要引入 aspose-words-15.8.0-jdk16.jar / aspose-cells-8.5.2.jar */public class PdfUtil { private static boolean getLicense() { boolean result = false; try { // license.xml应放在..\WebRoot\WEB-INF\classes路径下 InputStream is = PdfUtil.class.getClassLoader().getResourceAsStream("License.xml"); License aposeLic = new License(); aposeLic.setLicense(is); result = true; } catch (Exception e) { e.printStackTrace(); } return result; } /** * @param wordPath 需要被转换的word文件名 * @param pdfPath 转换之后pdf的文件 */ public static void doc2pdf(String wordPath, String pdfPath) { if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生 return; } try { long old = System.currentTimeMillis(); File file = new File(pdfPath); //新建一个pdf文档 FileOutputStream os = new FileOutputStream(file); Document doc = new Document(wordPath); //Address是将要被转化的word文档 doc.save(os, com.aspose.words.SaveFormat.PDF);//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换 long now = System.currentTimeMillis(); os.close(); System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒"); //转化用时 } catch (Exception e) { e.printStackTrace(); } } /** * @param excelPath 需要被转换的excel全路径带文件名 * @param pdfPath 转换之后pdf的全路径带文件名 */ public static void excel2pdf(String excelPath, String pdfPath) { if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生 return; } try { long old = System.currentTimeMillis(); Workbook wb = new Workbook(excelPath);// 原始excel路径 FileOutputStream fileOS = new FileOutputStream(new File(pdfPath)); wb.save(fileOS, com.aspose.cells.SaveFormat.PDF); fileOS.close(); long now = System.currentTimeMillis(); System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒"); //转化用时 } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { //word 和excel 转为pdf String fileName = "D:\word\file\demo.docx"; String pdfPath = "D:\word\pdf\demo..pdf"; doc2pdf(filePaths, pdfPath); }}复制代码

这里提供一下:License.xml文件

<License> <Data> <Products> <Product>Aspose.Total for Java</Product> <Product>Aspose.Words for Java</Product> </Products> <EditionType>Enterprise</EditionType> <SubscriptionExpiry>20991231</SubscriptionExpiry> <LicenseExpiry>20991231</LicenseExpiry> <SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber> </Data> <Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature></License>

好了,这个就是word转pdf的示例,也是比较简单啦!!!

好了,word转pdf,大概的实现,就是这样了!!!^_^

那我们就可以愉快的编写代码了!!!^_^

作者:llsydn链接:https://juejin.cn/post/7087036463035973640

0条大神的评论

发表评论