1. Maven依赖

    <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency><dependency><groupId>net.sf.jxls</groupId><artifactId>jxls-core</artifactId><version>1.0.5</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.poi.xwpf.converter.pdf-gae</artifactId><version>2.0.2</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency><dependency><groupId>com.aspose.words</groupId><artifactId>aspose-words</artifactId><version>19.5</version></dependency>
    
  2. aspose需要下载jar包(需要可以联系博主)

  3. license.xml(去除aspose的水印),放在resource目录下即可

    <?xml version="1.0" encoding="UTF-8"?><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>
    

  4. 部分关键代码
    调用生成word方法

    //data替换固定文本集合,2博主自用,int[]模板内有多少个表格
    generatePdf(data, 2, new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8}, enPdfPath, LanguageTypeEnum.en_US.getType(), 0);
    

    获取模板并调用生成word方法

    private void generateZhCNPdf(PdfDTO pdfDTO) {Map<String, Object> data = pdfDTO.getData();File file;InputStream is;file = new File(this.getClass().getResource("/template/temp.docx").getPath());is = Thread.currentThread().getContextClassLoader().getResourceAsStream("template/temps.docx");List<List<String[]>> mapList = pdfDTO.getMapList();int[] placeList = pdfDTO.getPlaceList();String pdfPath = pdfDTO.getPdfPath();String str = pdfPath.substring(0, pdfPath.lastIndexOf("/"));//判断文件夹是否存在File file1 = new File(str);if (!file1.exists() && !file1.isDirectory()) {file1.mkdirs();}new Thread() {@SneakyThrows@Overridepublic void run() {extractedZhCn(data,  file, is, mapList, placeList, pdfPath);}}.start();
    }
    

    生成word

             //临时存储文件,本地运行,需要注释该行FileUtils.copyInputStreamToFile(is, file);Thread.sleep(1000);//data固定填充内容map集合,file.getPath()模板地址,mapList需要循环填充表格的内容 placelist创建多少个表格的int[]CustomXWPFDocument doc = WorderToNewWordUtils.changWord(file.getPath(), data, mapList, placeList);//生成临时word文档FileOutputStream fopts = new FileOutputStream(pdfPath + ".docx");doc.write(fopts);fopts.close();
    

    changWord方法(填充数据)

        CustomXWPFDocument document = null;try {//获取docx解析对象document = new CustomXWPFDocument(POIXMLDocument.openPackage(inputUrl));//解析替换文本段落对象WorderToNewWordUtils.changeText(document, textMap);//解析替换表格对象WorderToNewWordUtils.changeTable(document, textMap, mapList,placeList);} catch (IOException e) {e.printStackTrace();}return document;
    

    changText()

        public static void changeText(CustomXWPFDocument document, Map<String, Object> textMap){//获取段落集合List<XWPFParagraph> paragraphs = document.getParagraphs();for (XWPFParagraph paragraph : paragraphs) {paragraph.setAlignment(ParagraphAlignment.LEFT);//判断此段落时候需要进行替换String text = paragraph.getText();if(checkText(text)){List<XWPFRun> runs = paragraph.getRuns();for (XWPFRun run : runs) {// 替换模板原来位置run.setText(changeValue(run.text(), textMap), 0);}}}
    }/*** 判断文本中时候包含$* @param text 文本* @return 包含返回true,不包含返回false*/public static boolean checkText(String text){boolean check  =  false;if(text.indexOf("$")!= -1){check = true;}return check;}/*** 匹配传入信息集合与模板* @param value 模板需要替换的区域* @param textMap 传入信息集合* @return 模板需要替换区域信息集合对应值*/public static String changeValue(String value, Map<String, Object> textMap) {Set<Map.Entry<String, Object>> textSets = textMap.entrySet();for (Map.Entry<String, Object> textSet : textSets) {// 匹配模板与替换值 格式${key}String key = textSet.getKey() ;if (value.indexOf(key) != -1) {if(textSet.getValue() != null){value = textSet.getValue().toString();}}}// 模板未匹配到区域替换为空if (checkText(value)) {value = "";}return value;
    }
    

    changeTable(填充循环数据)

     public static void changeTable(CustomXWPFDocument document, Map<String, Object> textMap, List<List<String[]>> mapList,int[] placeList){//获取表格对象集合List<XWPFTable> tables = document.getTables();//循环所有需要进行替换的文本,进行替换for (int i = 0; i < tables.size(); i++) {XWPFTable table = tables.get(i);if(checkText(table.getText())){List<XWPFTableRow> rows = table.getRows();System.out.println("简单表格替换:"+rows);//遍历表格,并替换模板eachTable(document,rows, textMap);}}int index=0;//操作word中的表格for (int i = 0; i < tables.size(); i++) {//只处理行数大于等于2的表格,且不循环表头XWPFTable table = tables.get(i);if(placeList != null){if(placeList[index]==i){List<String[]> list = mapList.get(index);//第二个表格使用daList,插入数据if (null != list && 0 < list.size()){insertTable(table, null,list,2);List<Integer[]> indexList = startEnd(list);for (int c=0;c<indexList.size();c++){//合并行mergeCellVertically(table,0,indexList.get(c)[0]+1,indexList.get(c)[1]+1);}}if(placeList.length > (index+1)){index++;}}}}
    }/*** 合并行* @param table* @param col 需要合并的列* @param fromRow 开始行* @param toRow 结束行*/
    public static void mergeCellVertically(XWPFTable table, int col, int fromRow, int toRow) {for(int rowIndex = fromRow; rowIndex <= toRow; rowIndex++){CTVMerge vmerge = CTVMerge.Factory.newInstance();vmerge.setVal(STMerge.RESTART);XWPFTableCell cell = table.getRow(rowIndex).getCell(col);CTTcPr tcPr = cell.getCTTc().getTcPr();if (tcPr != null) {tcPr.setVMerge(vmerge);} else {tcPr = CTTcPr.Factory.newInstance();tcPr.setVMerge(vmerge);cell.getCTTc().setTcPr(tcPr);}}
    }
    /*** 遍历表格* @param rows 表格行对象* @param textMap 需要替换的信息集合*/
    public static void eachTable(CustomXWPFDocument document, List<XWPFTableRow> rows , Map<String, Object> textMap){for (XWPFTableRow row : rows) {List<XWPFTableCell> cells = row.getTableCells();for (XWPFTableCell cell : cells) {//判断单元格是否需要替换if(checkText(cell.getText())){List<XWPFParagraph> paragraphs = cell.getParagraphs();for (XWPFParagraph paragraph : paragraphs) {paragraph.setAlignment(ParagraphAlignment.LEFT);paragraph.setKeepNext(false);List<XWPFRun> runs = paragraph.getRuns();for (XWPFRun run : runs) {Object ob = changeValue(run.toString(), textMap);if (ob instanceof String){run.setText((String)ob,0);}else if (ob instanceof Map){run.setText("",0);Map pic = (Map)ob;int width = Integer.parseInt(pic.get("width").toString());int height = Integer.parseInt(pic.get("height").toString());int picType = getPictureType(pic.get("type").toString());byte[] byteArray = (byte[]) pic.get("content");ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteArray);try {String blipId = document.addPictureData(byteInputStream,picType);document.addPictureToRun(run, blipId, document.getAllPictures().size() -1,width , height);} catch (Exception e) {e.printStackTrace();}}}}}}}
    }
    /*** 为表格插入数据,行数不够添加新行* @param table 需要插入数据的表格* @param tableList 第四个表格的插入数据* @param daList 第二个表格的插入数据* @param type 表格类型:1-第一个表格 2-第二个表格 3-第三个表格 4-第四个表格*/
    public static void insertTable(XWPFTable table, List<String> tableList,List<String[]> daList,Integer type){if (2 == type){//设置表格边框样式table.setLeftBorder(XWPFTable.XWPFBorderType.NONE , 0 , 0 ,"FFFFFF");table.setRightBorder(XWPFTable.XWPFBorderType.NONE , 0 , 0 ,"FFFFFF");table.setTopBorder(XWPFTable.XWPFBorderType.NONE , 0 , 0 ,"FFFFFF");table.setInsideVBorder(XWPFTable.XWPFBorderType.NONE , 0 , 0 , "FFFFFF");table.setInsideHBorder(XWPFTable.XWPFBorderType.SINGLE,0,0,"BEBEBE");table.setBottomBorder(XWPFTable.XWPFBorderType.SINGLE,0,0,"BEBEBE");//创建行和创建需要的列for(int i = 1; i < daList.size(); i++){//添加一个新行XWPFTableRow row = table.insertNewTableRow(1);for(int k=0; k<daList.get(0).length;k++){row.createCell();//根据String数组第一条数据的长度动态创建列row.setCantSplitRow(true);}}//创建行,根据需要插入的数据添加新行,不处理表头for(int i = 0; i < daList.size(); i++){//合计行是否加粗boolean blods = false;List<XWPFTableCell> cells = table.getRow(i+1).getTableCells();for(int j = 0; j < cells.size(); j++){//是否加粗合并boolean blod = false;//固定列是否合并boolean mell = false;XWPFTableCell cell02 = cells.get(j);// 设置水平居中,需要ooxml-schemas包支持CTTc cttc = cell02.getCTTc();CTTcPr ctPr = cttc.addNewTcPr();ctPr.addNewVAlign().setVal(STVerticalJc.CENTER);// 修改字体大小String s = daList.get(i)[j];//获取 CTPCTP ctP = (cttc.sizeOfPArray() == 0) ?cttc.addNewP() : cttc.getPArray(0);//getParagraph(ctP) 获取 XWPFParagraphXWPFParagraph par = cell02.getParagraph(ctP);CTP ctp = par.getCTP();CTPPr ctpPr = ctp.isSetPPr() ? ctp.getPPr() : ctp.addNewPPr();//设置行间距CTSpacing spacing = ctpPr.isSetSpacing()? ctpPr.getSpacing() : ctpPr.addNewSpacing();spacing.setAfter(BigInteger.valueOf(0));spacing.setBefore(BigInteger.valueOf(0));//注意设置行距类型为 EXACTspacing.setLineRule(STLineSpacingRule.EXACT);//1磅数是20spacing.setLine(BigInteger.valueOf(360));par.setAlignment(ParagraphAlignment.THAI_DISTRIBUTE);par.setKeepNext(false);Map<Object,Object> map = new HashMap<Object,Object>(1,0.70f);Map<Object,Object> map1 = new HashMap<Object,Object>(map);//par.setBorderTop();//XWPFRun   设置格式XWPFRun run = par.createRun();//加粗run.setBold(true);run.setFontSize(10);run.setText(s);//设置字体CTFonts font = run.getCTR().addNewRPr().addNewRFonts();//中文font.setEastAsia("思源");// ASCIIfont.setAscii("Poppins");font.setCs("Poppins");font.setHAnsi("Poppins");if (run.getText(0) != null && run.getText(0).contains("\n")) {String[] lines = run.getText(0).split("\n");if (lines.length > 0) {run.setText(lines[0], 0);for (int n = 1; n < lines.length; n++) {run.addBreak();run.setText(lines[n]);}}}//合并列(合并的列内需要有值,会保留前一列的值)mergeCellsHorizontal(table, i + 1, j + 2, j + 3);//设置靠齐方向par.setAlignment(ParagraphAlignment.RIGHT);}}}else if (4 == type){//插入表头下面第一行的数据for(int i = 0; i < tableList.size(); i++){XWPFTableRow row = table.createRow();List<XWPFTableCell> cells = row.getTableCells();cells.get(0).setText(tableList.get(i));}}
    }
    //合并列方法
    public static void mergeCellsHorizontal(XWPFTable table, int row, int startCell, int endCell) {for (int i = startCell; i <= endCell; i++) {XWPFTableCell cell = table.getRow(row).getCell(i);if (i == startCell) {// The first merged cell is set with RESTART merge valuecell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);}else {// Cells which join (merge) the first one, are set with CONTINUEcell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);}}
    }
    
  5. 转换pdf

    public static boolean zhCnWordToPDF(String sfileName, String toFileName) {if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生return false;}FileOutputStream os = null;try {long old = System.currentTimeMillis();File file = new File(toFileName); // 新建一个空白pdf文档os = new FileOutputStream(file);Document document= new Document(sfileName); // Address是将要被转化的word文档Document document1 = new Document(toFileName);//设置pdf字体DocumentBuilder documentBuilder = new DocumentBuilder(document1);documentBuilder.getFont().setName("思源黑体 CN");documentBuilder.getFont().setNameAscii("Poppins");documentBuilder.getFont().setNameOther("Poppins");TableCollection tables = document.getFirstSection().getBody().getTables();for (Table table : tables) {RowCollection rows = table.getRows();table.setAllowAutoFit(false);for (Row row : rows) {CellCollection cells = row.getCells();for (Cell cell : cells) {CellFormat cellFormat = cell.getCellFormat();cellFormat.setFitText(false);cellFormat.setWrapText(true);}}}document.save(os, SaveFormat.PDF);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,// EPUB, XPS, SWF 相互转换long now = System.currentTimeMillis();System.out.println("pdf转换成功,共耗时:" + ((now - old) / 1000.0) + "秒"); // 转化用时} catch (Exception e) {e.printStackTrace();return false;}finally {if (os != null) {try {os.flush();os.close();} catch (IOException e) {e.printStackTrace();}}}return true;
    }
    

    验证license

    public static boolean getLicense() {boolean result = false;InputStream is = null;try {Resource resource = new ClassPathResource("/license.xml");is = resource.getInputStream();License aposeLic = new License();aposeLic.setLicense(is);result = true;} catch (Exception e) {e.printStackTrace();}finally {if (is != null) {try {is.close();} catch (IOException e) {e.printStackTrace();}}}return result;}
    

springBoot+poi+aspose实现根据word模板生成文件并转换pdf相关推荐

  1. POI 3.9根据word模板生成报表

    XWPFDocument对象 POI是apache提供的可以操作word文档的第三方jar.POI能操作word是使用XWPFDocument对象. XWPFDocument对象可以解析docx文件, ...

  2. Java读取模板文件您好,RtfTemplate 读取word模板生成文件

    try { response.reset(); response.setContentType("txt/rtf; charset=GBK"); String fileName = ...

  3. apache poi使用例_使用java Apache poi 根据word模板生成word报表例子

    [实例简介] 使用java Apache poi 根据word模板生成word报表 仅支持docx格式的word文件,大概是word2010及以后版本,doc格式不支持. 使用说明:https://b ...

  4. 使用java Apache poi 根据word模板生成word报表

    使用java Apache poi 根据word模板生成word报表 使用poi读取word模板,替换word中的{text}标签,并根据自定义标签循环生成表格或表格中的行. 代码示例下载:https ...

  5. 使用word模板生成word文档的各类方案

    使用word模板生成word文档的各类方案 生成word的各种方案 word另存xml进行后续处理 2003版本word(.doc)的xml处理并生成word 2007版本word(.docx)的xm ...

  6. 根据word模板生成word和PDF

    根据word模板生成word和PDF 需求:有一个固定的合同模板,在vue前台填写指定的信息,替换合同模板指定的内容 我们使用的默认模板内容如图: 我们在前端填写的字段就是合同名称.项目名称和项目金额 ...

  7. java 根据word模板生成word文件

    Java可以使用Apache POI库来生成Word文件,并且也可以使用freemarker等模板引擎来实现根据Word模板生成Word文件的功能. 下面是一个简单的示例代码,可以帮助您快速入门. 模 ...

  8. word模板生成word报表文档

    主要功能为根据word模板生成word报表文档,注意引用Interop.Word.dll; 首先要生成word程序对象 Word.Application app = new Word.Applicat ...

  9. 使用com.aspose.words将word模板转为PDF乱码解决方案(window下正常)

    使用com.aspose.words将word模板转为PDF乱码解决方案(window下正常) 参考文章: (1)使用com.aspose.words将word模板转为PDF乱码解决方案(window ...

最新文章

  1. 过去可忆,未来可期(随心录+杂记)
  2. 手写带注册中心的rpc框架(Netty版和Socket版)
  3. 70+漂亮且极具亲和力的导航菜单设计推荐
  4. border,padding,margin盒模型理解
  5. JavaScript实现向OL列表内动态添加LI元素的方法
  6. 贪心算法之取手套问题(牛客)
  7. Git Diff 魔法
  8. python基础编程语法-编程入门02:Python基础语法
  9. 【原创】软件团队建设和管理--之我见
  10. cocos2d-x-3.x 场景(3)场景切换特效
  11. 使用python调用openmpi编译的MPI 动态库报错:mca_base_component_repository_open: unable to open mca_patcher_overwri
  12. k8s运维-06-kubectl delete node的过程
  13. 解压软件Bandizip
  14. Drug Discovery Today| 频繁命中化合物:高通量筛选中需警惕的假阳性结果
  15. 商业模式是利益相关者的交易结构
  16. linux中i的英文单词,Linux下gcc/g++中-I(i的大写)、-L和-l
  17. html name选择器,iframe标签的name属性
  18. 《一名网络工程师的自我修养》--子网划分
  19. Gauss工作—学习笔记
  20. 看Google收购Nest

热门文章

  1. 酒店管理系统毕业设计
  2. ubuntu下 U盘盘符重命名修改方法
  3. java中泛型的详解
  4. 逻辑思维不好能学java吗_没思维能力怎么学java?
  5. 程序员之剑法三套-(原来程序员也是“剑客”)
  6. 更新Jetson TX2内核及dtb文件
  7. Vim插件之vim-polyglot
  8. 2020-07-28 httprunner+locusts+python接口测试框架
  9. Azkaban添加微信报警功能
  10. 大家一起来讨论讨论像56和优酷等哪些网站,里面的动感相册功能是怎样实现的!...