文章目录

  • 一、引入包
    • 1.1在pom引入
    • 1.2 因为我们的项目是打包成jar,所以以上方法在本地idea运行没有问题,linux系统不行
    • 1.2.1解决方法1
    • 1.2.2解决方法2
  • 二、配置文件--License.xml--去除水印
    • 2.1 license.xml直接放到resources的根目录下即可
    • 2.2 工具类
  • 三、调用
  • 效果

一、引入包

链接: https://pan.baidu.com/s/13V2ihOpRoLf3R9MFCH2kHQ?pwd=be64 提取码: be64 复制这段内容后打开百度网盘手机App,操作更方便哦

1.1在pom引入

<dependency><groupId>com.aspose</groupId><artifactId>aspose-words</artifactId><version>15.8.0</version><scope>system</scope><systemPath>${project.basedir}/src/main/resources/lib/aspose-words-15.8.0.jar</systemPath></dependency>

1.2 因为我们的项目是打包成jar,所以以上方法在本地idea运行没有问题,linux系统不行

1.2.1解决方法1

推荐

<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><!-- 打包时会将本地jar一起打包 --><configuration><includeSystemScope>true</includeSystemScope></configuration>     </plugin></plugins>
</build>

或者是

<build><resources><resource><directory>lib</directory><targetPath>/BOOT-INF/lib/</targetPath><includes><include>**/*.jar</include></includes></resource></resources></build>

1.2.2解决方法2

对比方法一,我觉得还是挺垃圾的,谁想动一个摇摇欲坠的项目

         <dependency><groupId>com.aspose</groupId><artifactId>aspose-words</artifactId><version>15.8.0</version></dependency>
该语句中参数:
DgroupId :组id 【对应pom中的groupId】
DartifactId:项目id 【对应pom中的artifactId】
Dversion:版本号 【对应pom中的version】
Dfile:jar包的绝对路径
Dpackaging:是什么包
DgeneratePom:是否生成pom

直接使用maven命令

mvn install:install-file -Dfile=C:\Users\yhc\Desktop\aspose-words-15.8.0.jar -DgroupId=com.aspose -DartifactId=aspose-words -Dversion=15.8.0 -Dpackaging=jar -DgeneratePom=true

不想运行也没关系,我放在云盘了,自行拷贝

生成这个文件夹,把这个放在你们的maven仓库就行了

二、配置文件–License.xml–去除水印

2.1 license.xml直接放到resources的根目录下即可

<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>

2.2 工具类

import cn.hutool.system.OsInfo;
import cn.hutool.system.SystemUtil;
import com.aspose.words.Document;
import com.aspose.words.FontSettings;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import lombok.SneakyThrows;
import org.springframework.core.io.ClassPathResource;
import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import java.io.InputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
import java.util.Map.Entry;/*** 通过word模板生成新的word工具类*/
public class WordUtils {/*** 加载license 用于破解 不生成水印**/@SneakyThrowsprivate static void getLicense() {try (InputStream inputStream = WordUtils.class.getClassLoader().getResourceAsStream("license.xml")) {License license = new License();license.setLicense(inputStream );//乱码问题garbledCode();}}/*** 乱码问题*/@SneakyThrowsprivate static void  garbledCode() {//把用到的字体包从windows的C:\Windows\Fonts里所有文件,复制到linux的/usr/share/fonts/windows下。OsInfo osInfo = SystemUtil.getOsInfo();if(osInfo.isLinux()){FontSettings.setFontsFolder("/usr/share/fonts/windows"+File.separator, true);}}/*** 获取Resource路径* @return*/public static String getResourcePath(){String path = Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResource("")).getPath();String osName = System.getProperty("os.name");if (osName.contains("Windows")) {return path.substring(1);}else{path="/usr/local";}return path;}/*** word转pdf* @param outputUrl word文件保存的路径* @return pdf生成的路径*/@SneakyThrowspublic static String wordToPdf(String outputUrl) {//生成pdfString outputPdf = outputUrl.replace("docx", "pdf");File filePdf = new File(outputPdf);FileOutputStream streamPdf = new FileOutputStream(filePdf);//凭证 不然切换后有水印getLicense();//开始渲染转化,并且输出Document doc = new Document(outputUrl); // Address是将要被转化的word文档doc.save(streamPdf, SaveFormat.PDF);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,  EPUB, XPS, SWF 相互转换streamPdf.close();return outputPdf;}/*** web下载文件* @param path pdf临时保存路径* @param response*/public static void downResult(String  path, HttpServletResponse response){try{File file = new File(path);boolean exists = file.exists();if (!exists){throw new Exception("文件不存在!");}// 获取文件名String filename = file.getName();// 获取文件后缀名String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();// 将文件写入输入流FileInputStream fileInputStream = new FileInputStream(file);InputStream fis = new BufferedInputStream(fileInputStream);byte[] buffer = new byte[fis.available()];fis.read(buffer);fis.close();// 清空responseresponse.reset();// 设置response的Headerresponse.setCharacterEncoding("UTF-8");//Content-Disposition的作用:告知浏览器以何种方式显示响应返回的文件,用浏览器打开还是以附件的形式下载到本地保存//attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3"// filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));// 告知浏览器文件的大小response.addHeader("Content-Length", "" + file.length());OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());//设置响应格式,已文件流的方式返回给前端。response.setContentType("application/octet-stream");outputStream.write(buffer);outputStream.flush();} catch (Exception e) {e.printStackTrace();}}/*** 判断文本中时候包含$** @param text 文本* @return 包含返回true, 不包含返回false*/public static boolean checkText(String text) {boolean check = false;if (text.indexOf("$") != -1) {check = true;}return check;}/*** 根据模板生成新word文档* 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入** @param inputUrl  模板存放地址* @param outputUrl 新文档存放地址* @param textMap   需要替换的信息集合* @param tableList 需要插入的表格信息集合*/public static boolean changWord(String inputUrl, String outputUrl,Map<String, String> textMap, List<List<String[]>> tableList) {//模板转换默认成功boolean changeFlag = true;try {//获取docx解析对象XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));//解析替换文本段落对象WordUtils.changeText(document, textMap);//解析替换表格对象WordUtils.changeTable(document, textMap, tableList);//生成新的wordFile file = new File(outputUrl);FileOutputStream stream = new FileOutputStream(file);document.write(stream);stream.close();System.out.println("成功生成!" + outputUrl);} catch (IOException e) {e.printStackTrace();changeFlag = false;}return changeFlag;}// word表格跨列合并单元格//row 指定行、fromCell 开始列数、toCell 结束列数。public static void mergeColumn(XWPFTable table, int row, int fromCell, int toCell) {for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {XWPFTableCell cell = table.getRow(row).getCell(cellIndex);if (cellIndex == fromCell) {cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);} else {cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);}}}// word表格跨行并单元格//col 指定列、fromRow 开始行、toRow 结束行。public static void mergeLine(XWPFTable table, int col, int fromRow, int toRow) {for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {XWPFTableCell cell = table.getRow(rowIndex).getCell(col);if (rowIndex == fromRow) {cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);} else {cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);}}}/*** 替换段落文本** @param document docx解析对象* @param textMap  需要替换的信息集合*/public static void changeText(XWPFDocument document, Map<String, String> textMap) {//获取段落集合List<XWPFParagraph> paragraphs = document.getParagraphs();for (XWPFParagraph paragraph : paragraphs) {//判断此段落时候需要进行替换String text = paragraph.getText();if (checkText(text)) {List<XWPFRun> runs = paragraph.getRuns();for (XWPFRun run : runs) {//替换模板原来位置// run.setText(changeValue(run.toString(), textMap),0);String textValue = changeValue(run.toString(), textMap);run.setText(textValue, 0);}}}}/*** 遍历表格** @param rows    表格行对象* @param textMap 需要替换的信息集合*/public static void eachTable(List<XWPFTableRow> rows, Map<String, String> 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) {List<XWPFRun> runs = paragraph.getRuns();for (XWPFRun run : runs) {run.setText(changeValue(run.toString(), textMap), 0);}}}}}}/*** 为表格插入数据,行数不够添加新行** @param table     需要插入数据的表格* @param tableList 插入数据集合*/public static void insertTable(XWPFTable table, List<String[]> tableList) {//创建行,根据需要插入的数据添加新行,不处理表头for (int i = 1; i < tableList.size(); i++) {XWPFTableRow row = table.createRow();}//遍历表格插入数据List<XWPFTableRow> rows = table.getRows();for (int i = 1; i < rows.size(); i++) {XWPFTableRow newRow = table.getRow(i);List<XWPFTableCell> cells = newRow.getTableCells();for (int j = 0; j < cells.size(); j++) {XWPFTableCell cell = cells.get(j);cell.setText(tableList.get(i - 1)[j]!=null?tableList.get(i - 1)[j]:"");}}}/*** 替换表格对象方法** @param document  docx解析对象* @param textMap   需要替换的信息集合* @param tableList 需要插入的表格信息集合*/public static void changeTableDynamic(XWPFDocument document, Map<String, String> textMap,List<List<String[]>> tableList, List<List<int[]>> mergeLineTable, List<List<int[]>> mergeColumnTable) {//获取表格对象集合List<XWPFTable> tables = document.getTables();for (int i = 0; i < tables.size(); i++) {XWPFTable table = tables.get(i);if (mergeLineTable == null && mergeColumnTable == null) {insertTableDynamicCol(table, tableList.get(i));} else {insertTableMergeDynamicCol(table, tableList.get(i), mergeLineTable.get(i), mergeColumnTable.get(i));}}}/*** 替换表格对象方法-->(带合并单元格方法)** @param document  docx解析对象* @param textMap   需要替换的信息集合* @param tableList 需要插入的表格信息集合*/public static void changeTable(XWPFDocument document, Map<String, String> textMap,List<List<String[]>> tableList) {//获取表格对象集合List<XWPFTable> tables = document.getTables();for (int i = 0; i < tables.size(); i++) {//只处理行数大于等于2的表格,且不循环表头XWPFTable table = tables.get(i);if (table.getRows().size() > 1) {//判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入if (checkText(table.getText())) {List<XWPFTableRow> rows = table.getRows();//遍历表格,并替换模板eachTable(rows, textMap);} else {//                  System.out.println("插入"+table.getText());insertTable(table, tableList.get(i));}}}}/*** 为表格插入数据,行数不够添加新行 列不够添加新列** @param table     需要插入数据的表格* @param tableList 插入数据集合*/public static void insertTableDynamicCol(XWPFTable table, List<String[]> tableList) {//遍历表格插入数据List<XWPFTableRow> rows = table.getRows();// 列int col = rows.get(0).getTableCells().size();//创建列,根据需要插入的数据添加新列for (int i = col; i < tableList.get(0).length; i++) {table.addNewCol();}//创建行,根据需要插入的数据添加新行for (int i = rows.size() - 1; i < tableList.size(); i++) {XWPFTableRow row = table.createRow();}table.removeRow(0);for (int i = 0; i < rows.size(); i++) {XWPFTableRow newRow = table.getRow(i);List<XWPFTableCell> cells = newRow.getTableCells();for (int j = 0; j < cells.size(); j++) {XWPFTableCell cell = cells.get(j);//设置表格内容水平居中CTTc cttc = cell.getCTTc();CTTcPr ctPr = cttc.addNewTcPr();ctPr.addNewVAlign().setVal(STVerticalJc.CENTER);cttc.getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);cell.setText(tableList.get(i)[j]);}}}/*** 为表格插入数据,行数不够添加新行 列不够添加新列--->带合并单元格** @param table     需要插入数据的表格* @param tableList 插入数据集合*/public static void insertTableMergeDynamicCol(XWPFTable table, List<String[]> tableList, List<int[]> mergeLine, List<int[]> mergeColumn) {//遍历表格插入数据List<XWPFTableRow> rows = table.getRows();// 列int col = rows.get(0).getTableCells().size();//创建列,根据需要插入的数据添加新列if (tableList.size() > 0) {for (int i = col; i < tableList.get(0).length; i++) {table.addNewCol();}}//创建行,根据需要插入的数据添加新行for (int i = rows.size() - 1; i < tableList.size(); i++) {XWPFTableRow row = table.createRow();}table.removeRow(0);for (int i = 0; i < rows.size(); i++) {XWPFTableRow newRow = table.getRow(i);List<XWPFTableCell> cells = newRow.getTableCells();for (int j = 0; j < cells.size(); j++) {XWPFTableCell cell = cells.get(j);//设置表格内容水平居中CTTc cttc = cell.getCTTc();CTTcPr ctPr = cttc.addNewTcPr();ctPr.addNewVAlign().setVal(STVerticalJc.CENTER);cttc.getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);cell.setText(tableList.get(i)[j]);}}if (tableList.size() > 0) {if (mergeLine != null && !mergeLine.isEmpty()) {for (int i = 0; i < mergeLine.size(); i++) {mergeLine(table, mergeLine.get(i)[0], mergeLine.get(i)[1], mergeLine.get(i)[2]);}}if (mergeColumn != null && !mergeColumn.isEmpty()) {for (int i = 0; i < mergeColumn.size(); i++) {mergeColumn(table, mergeColumn.get(i)[0], mergeColumn.get(i)[1], mergeColumn.get(i)[2]);}}// 设置列宽table.setWidthType(TableWidthType.DXA);//            //手动添加新的一行
//            XWPFTableCell cell = table.getRow(rows.size() - 1).getCell(0);
//            /** 设置水平居中 */
//            CTTc cttc = cell.getCTTc();
//            CTTcPr ctPr = cttc.addNewTcPr();
//            ctPr.addNewVAlign().setVal(STVerticalJc.CENTER);
//            cttc.getPList().get(0).addNewPPr().addNewJc().setVal(STJc.RIGHT);
//
//
//            XWPFParagraph para = cell.getParagraphArray(0);
//
//            //一个XWPFRun代表具有相同属性的一个区域。
//            XWPFRun run = para.createRun();
//
//            run.setText("小计:");
//            run = para.createRun();
//            run.setColor("FF0000");
//            run.setText(tableList.get(tableList.size() - 1)[tableList.get(0).length - 1]);
//            run = para.createRun();
//            run.setColor("000000");
//            run.setText("元");}}/*** 匹配传入信息集合与模板** @param value   模板需要替换的区域* @param textMap 传入信息集合* @return 模板需要替换区域信息集合对应值*/public static String changeValue(String value, Map<String, String> textMap) {Set<Entry<String, String>> textSets = textMap.entrySet();for (Entry<String, String> textSet : textSets) {//匹配模板与替换值 格式${key}String key = "${" + textSet.getKey() + "}";if (value.indexOf(key) != -1) {//全部参数替换// value = textSet.getValue();//仅替换参数value = value.replace(key, textSet.getValue()==null?"无":textSet.getValue());}}//模板未匹配到区域替换为空if (checkText(value)) {value = "";}return value;}/*** 关闭输入流** @param is*/private static void close(InputStream is) {if (is != null) {try {is.close();} catch (IOException e) {e.printStackTrace();}}}/*** 关闭输出流** @param os*/private static void close(OutputStream os) {if (os != null) {try {os.close();} catch (IOException e) {e.printStackTrace();}}}/*** 实例1** 根据模板生成Pdf并下载* 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入* @param dynamic  模板存放地址 true 有合并的内容* @param inputUrl  模板存放地址* @param response* @param textMap   需要替换的信息集合* @param tableList 需要插入的表格信息集合*/public static String changWordToPdfDownloadUrl(boolean dynamic, String inputUrl, String outputUrl, String fileName, HttpServletResponse response,Map<String, String> textMap, List<List<String[]>> tableList, List<List<int[]>> mergeLineTable, List<List<int[]>> mergeColumnTable) {//模板转换默认成功boolean changeFlag = true;try {//获取docx解析对象File inputWordFile = new File(inputUrl);InputStream source = new FileInputStream(inputWordFile);XWPFDocument document = new XWPFDocument(source);//解析替换文本段落对象WordUtils.changeText(document, textMap);//解析替换表格对象 true 有合并的内容if (!dynamic) {WordUtils.changeTable(document, textMap, tableList);} else {// true 有合并的内容WordUtils.changeTableDynamic(document, textMap, tableList, mergeLineTable, mergeColumnTable);}//生成新的wordFile file = new File(outputUrl);FileOutputStream stream = new FileOutputStream(file);document.write(stream);stream.close();//word转化pdf 渲染String outputPdf= wordToPdf(outputUrl);//web下载downResult(outputPdf,response);// 删除过渡word文件if (file.exists()) {file.delete();}// 删除过渡pdf文件File filePdf=  new File(outputPdf);if (filePdf.exists()) {filePdf.delete();}close(source);return outputPdf;} catch (Exception e) {e.printStackTrace();}return null;}/*** 实例2** @param dynamic* @param inputUrl* @param outputUrl* @param fileName* @param response* @param textMap* @param tableList* @param mergeLineTable* @param mergeColumnTable* @return*/public static Map<String, String> changWordToPdfDownloadUrlAndMD5(boolean dynamic, String inputUrl, String outputUrl, String fileName, HttpServletResponse response,Map<String, String> textMap, List<List<String[]>> tableList, List<List<int[]>> mergeLineTable, List<List<int[]>> mergeColumnTable) {//模板转换默认成功boolean changeFlag = true;try {//获取docx解析对象File inputWordFile = new File(inputUrl);InputStream source = new FileInputStream(inputWordFile);XWPFDocument document = new XWPFDocument(source);//解析替换文本段落对象WordUtils.changeText(document, textMap);//解析替换表格对象if (!dynamic) {WordUtils.changeTable(document, textMap, tableList);} else {/*** mergeLineTable,行设置* mergeColumnTable,列设置*/WordUtils.changeTableDynamic(document, textMap, tableList, mergeLineTable, mergeColumnTable);}//生成新的wordFile file = new File(outputUrl);FileOutputStream stream = new FileOutputStream(file);document.write(stream);stream.close();//word转化pdf 渲染String outputPdf= wordToPdf(outputUrl);//web下载downResult(outputPdf,response);File filePdf=  new File(outputPdf);String stringMD5 = MD5Util.MD5File(filePdf);Map<String, String> result = new HashMap<>();result.put("url", outputPdf);result.put("MD5", stringMD5);// 删除过渡word文件if (file.exists()) {file.delete();}// 删除过渡pdf文件if (filePdf.exists()) {filePdf.delete();}close(source);return result;} catch (Exception e) {e.printStackTrace();}return null;}/*** 预付款证明单pdf* @param dynamic* @param inputStream 原始文件输入流* @param outputUrl 输出文件 路径和名称定义* @param response* @param textMap 替换${XX}内容* @param tableList  插入表数据* @param mergeLineTable 行合并* @param mergeColumnTable 列合并* @return*/public static Map<String, String> exportProofOfAdvancePayment(boolean dynamic, InputStream inputStream, String outputUrl, HttpServletResponse response,Map<String, String> textMap, List<List<String[]>> tableList, List<List<int[]>> mergeLineTable, List<List<int[]>> mergeColumnTable) {//模板转换默认成功boolean changeFlag = true;try {InputStream source = inputStream;XWPFDocument document = new XWPFDocument(inputStream);//解析替换文本段落对象WordUtils.changeText(document, textMap);//解析替换表格对象if (!dynamic) {WordUtils.changeTable(document, textMap, tableList);} else {/*** mergeLineTable,行设置* mergeColumnTable,列设置*/WordUtils.changeTableDynamic(document, textMap, tableList, mergeLineTable, mergeColumnTable);}//生成新的wordFile file = new File(outputUrl);FileOutputStream stream = new FileOutputStream(file);document.write(stream);stream.close();//word转化pdf 渲染String outputPdf= wordToPdf(outputUrl);//web下载downResult(outputPdf,response);File filePdf=  new File(outputPdf);String stringMD5 = MD5Util.MD5File(filePdf);Map<String, String> result = new HashMap<>();result.put("url", outputPdf);result.put("MD5", stringMD5);// 删除过渡word文件if (file.exists()) {file.delete();}// 删除过渡pdf文件if (filePdf.exists()) {filePdf.delete();}close(source);return result;} catch (Exception e) {e.printStackTrace();}return null;}}

MD5File工具类

/***  @author   yanghucheng*  @created  2017/08/14*  Copyright (C),2007-2016, LonBon Technologies Co. Ltd. All Rights Reserved.*/
package com.zdft.warehouse.common.util.pdf;import org.apache.commons.codec.binary.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;/*** The type Md 5 util.** @author  yanghucheng* @Date    2017/08/14*/
public class MD5Util {private static Logger logger = LoggerFactory.getLogger(MD5Util.class);/*** Byte array to hex string string.** @param b the b* @return the string*/private static String byteArrayToHexString(byte b[]) {StringBuffer resultSb = new StringBuffer();for (int i = 0; i < b.length; i++) {resultSb.append(byteToHexString(b[i]));}return resultSb.toString();}/*** Byte to hex string string.** @param b the b* @return the string*/private static String byteToHexString(byte b) {int n = b;if (n < 0) {n += 256;}int d1 = n / 16;int d2 = n % 16;return hexDigits[d1] + hexDigits[d2];}/*** Md 5 encode string.** @param origin      the origin* @param charsetname the charsetname* @return the string*/public static String MD5Encode(String origin, String charsetname) {String resultString = null;try {resultString = new String(origin);MessageDigest md = MessageDigest.getInstance("MD5");if (charsetname == null || "".equals(charsetname)) {resultString = byteArrayToHexString(md.digest(resultString.getBytes()));} else {resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));}} catch (IOException|NoSuchAlgorithmException e) {e.printStackTrace();logger.error(e.getMessage());return null;}return resultString.toUpperCase();}/*** Md 5 encode utf 8 string.** @param origin the origin* @return the string*/public static String MD5EncodeUtf8(String origin) {//origin = origin +PropertiesUtil.getProperty("password.salt", "");return MD5Encode(origin, "utf-8");}public static String MD5File(File file) {FileInputStream fileInputStream = null;try {MessageDigest MD5 = null;MD5 = MessageDigest.getInstance("MD5");fileInputStream = new FileInputStream(file);byte[] buffer = new byte[8192];int length;while ((length = fileInputStream.read(buffer)) != -1) {MD5.update(buffer, 0, length);}return new String(Hex.encodeHex(MD5.digest()));} catch (IOException | NoSuchAlgorithmException e) {logger.error(e.getMessage());return null;}finally {try {if (fileInputStream != null){fileInputStream.close();}} catch (IOException e) {logger.error(e.getMessage());}}}/*** The constant hexDigits.*/private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5","6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};}

三、调用

控制层

    @GetMapping("/export/test")@ApiOperation("打印预付款支付证明单")public void exportProofOfAdvancePayment( HttpServletResponse response) throws IOException {prepaymentPoolDetailService.exportProofOfAdvancePaymentV2(response);}

service

void exportProofOfAdvancePaymentV2(HttpServletResponse response) throws IOException;

serviceImpl

    @Overridepublic void exportProofOfAdvancePaymentV2(HttpServletResponse response) throws IOException {DecimalFormat df = new DecimalFormat("#,##0.00");InputStream inputStream = new ClassPathResource("/exportModel/预付款支付证明单.docx").getInputStream();String filepathOut = WordUtils.getResourcePath() + "/" + UUID.randomUUID().toString() + "_预付款支付证明单.docx";Map<String, String> baseMap = new HashMap<String, String>();//支付申请时间baseMap.put("createTime",DateUtils.format(new Date()));//打印日期baseMap.put("newTime",DateUtils.format(new Date()));//业务申办人baseMap.put("createUser","业务申办人");//供应商baseMap.put("vendorName","供应商");//核算公司baseMap.put("vendorCorpName","核算公司");//应付款金额baseMap.put("deductionAmount","55.00");//大写金额baseMap.put("money", "五十五元整");//付款方式baseMap.put("payMethod","现金支付");//收款人baseMap.put("payee","代码浪人");//已发放金额baseMap.put("grantAdvanceAmount","10.20");//本次发放金额baseMap.put("thisMoney","56.21");//开户行baseMap.put("bankName","中国银行");//帐号baseMap.put("account","45646465");//备注baseMap.put("remark","无");//单据号baseMap.put("processNumber","yfk123");//单据号baseMap.put("prepaymentNo","No123");//申请部门baseMap.put("dept","部门");List<List<String[]>> tableList = new ArrayList<>();//建立所要插入每个表的所有数据List<String[]> tableDate=new ArrayList<>();//具体表数据int index=1;for (int i = 1; i < 2; i++) {//            tableDate.add(new String[]{"","","","","",""});tableDate.add(new String[]{index + "", "现金支付","566", DateUtils.format(new Date()), "备注"});index++;}tableList.add(tableDate);tableList.add(tableDate);try {WordUtils.exportProofOfAdvancePayment(false, inputStream, filepathOut, response, baseMap, tableList, null, null);} catch (Exception e) {throw e;}}

效果

java-word模板转化为pdf相关推荐

  1. java word模板替换多行_Java动态替换word模板的最佳实践

    poi-tl 基于word的模板渲染(替换)组件 对docx格式的文档增加模板语法,增加渲染模板的方便性,目前支持对段落.页眉.页脚.表格的文本.图片.表单渲染. 对于word模板替换,我们不仅要考虑 ...

  2. java 通过模板生成导出PDF方案对比

    需求背景 目前项目中有通过 上传word模板,结合用户填写数据,导出渲染后的PDF数据,提升数据安全性.现记录一下使用过程及遇到的问题 项目方案 Adobe Acrobat Pro 打开刚刚制作的pd ...

  3. java word 模板_java根据模板生成word文件

    JAVA生成word模板程序步骤 1. 将freemarker-2.3.13.jar复制到项目\WEB-INF\lib目录下 2. 编辑模板文件 (1) 将DOC文件另存为xml文件,将xml文件在e ...

  4. java word模板poi生成文件_利用poi读取word模板文件生成新的word文档

    利用poi读取word模板文件生成新的word文档 利用poi读取word模板文件,并回填逻辑数据,生成并导出需要的word文档源码.解决模板读取异常问题,提供wordUtils工具类(各种功能实现) ...

  5. Java Word模板引擎-Poi-tl

    本文内容从Poi-tl官方文档摘录,poi-tl是一个基于Java POI的Word模板引擎,有着非常强大的功能 此处只摘录了一些我现在需要用到的功能 文章目录 一.简单示例 1.准备一个模板文档 ` ...

  6. java word模板替换多行_java poi word模板替换段落的换行显示

    在poi操作word模板进行数据替换时,会存在替换的段落需要换行的情况,由于传入的都是字符串,之前在网上搜索过一些处理方法都没有效果,如给字符串添加:"\r","\r\n ...

  7. java word 模板_java通过word模板生成word文档

    public static void main(String[] args) { //模板.文件.图片路径 String workPath=System.getProperty("user. ...

  8. java word文档转PDF xdocreport在centos7生成PDF不显示中文

    关键字:java xdocreport centos7 PDF 中文 不显示 在我的项目中出现了问题 生产(Linux)上就是word转pdf没有汉字显示,只有字母和数字. 因为liunx系统上,没有 ...

  9. java word模板占位符_word模板导出的几种方式:第一种:占位符替换模板导出(只适用于word中含有表格形式的)...

    1.占位符替换模板导出(只适用于word中含有表格形式的): /// /// 使用替换模板进行到处word文件 /// public class WordUtility { private objec ...

最新文章

  1. C语言长度为0的数组
  2. excel函数vloopup使用方法
  3. 根据相机内参进行图像去畸变
  4. 流程管理软件如何适应变化
  5. Dynamic CRM 2013学习笔记(四十二)流程5 - 实时/同步工作流(Workflow)用法图解...
  6. Vue-CLI and Leaflet (9): 点聚合 Leaflet.markercluster
  7. 键盘按键用硅胶材料更好
  8. ios模拟器安装证书
  9. js回避ie缓存的办法
  10. 【OCR 文字识别】Python中一个不错的OCR库-EasyOCR
  11. 微信小程序 + 腾讯位置服务SDK 实现路线规划
  12. elementary 安装常用软件
  13. 基于医疗RFID手术用品智能柜管理应用方案
  14. JavaMail连接Office 365使用XOAUTH2身份认证
  15. 赛宁网安合作伙伴大会成功举办,重磅发布SCBaaS服务!
  16. ubuntu18.04配置deepo深度学习环境(cuda + cudnn + nvidia-docker + deepo)--超级细致,并把遇到的错误和所有解决方案都列出来了
  17. Vue中的视频播放插件( vue-video-player )
  18. oracle数据库修改pga,18.1.2 修改PGA
  19. 结对编程之单元测试 201421123108 王坤彬
  20. 计算机应用当兵分配到哪,参军是怎么分配省份的 当兵会被分配到哪里

热门文章

  1. 计算机组装教学反思,中职计算机信息化课堂的落实与教学反思
  2. beego利用casbin进行权限管理——第二节 策略存储
  3. 地铁fas系统需要服务器吗,地铁FAS系统简介及操作
  4. [css] flex 间距 gap 折行滚动(九宫格 四宫格 横向滚动)
  5. 2021-10-07每日刷题打卡
  6. RoBERTa:A Robustly Optimized BERT Pretraining Approach(2019-7-26)
  7. VScode行内样式提醒,补全插件
  8. python中对类变量的访问形式_Python 面向对象中类、方法、变量、实例化和对象的概念,python定义类和访问权限?python三大支柱封装、继承和多态-立地货...
  9. 【NOJ1326】【算法实验三】推箱子
  10. 倾向性得分(psm)在数据分析中的应用。