主要的学习和踩坑

  • word模板1类型只有文字的只要用这种方式实现非常好,没有图片的word模板;特别注意的是支持.doc的模板
    • 2 第二种带图片的word模板,只支持 docx的
    • 4 word转pdf,最后还是找了 使用libreoffice来进行转pdf 这种方式
    • 使用libreoffice来进行转pdf 这种方式需要安装的软件
    • 最后付一下maven依赖:是word模板的
  • 当报错时 Error: source file could not be loaded

word模板1类型只有文字的只要用这种方式实现非常好,没有图片的word模板;特别注意的是支持.doc的模板

直接上代码
1 word模板转换工具类

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Range;/*** * 此处填写类简介* <p>* word生成* </p>* @author admin* @since jdk1.6* 2019年11月14日*  */public class DocUtils {/*** * @param tmpFile  模板文件路径* @param contentMap 需要替换的文字* @param exportFile 输出的文件路径* @throws FileNotFoundException*/public static void getBuild(String  tmpFile, Map<String, Object> contentMap, String exportFile) throws FileNotFoundException{//三种实现 InputStream 流方式File f = new File(tmpFile);   InputStream in = new FileInputStream(f);
//   2       InputStream inputStream = DocUtil.class.getClassLoader().getResourceAsStream("static/book.doc");
//    3      InputStream inputStream1 = Thread.currentThread().getContextClassLoader().getResourceAsStream("content/book.docx");HWPFDocument document = null; try {document = new HWPFDocument(in);} catch (IOException e) {e.printStackTrace();}// 读取文本内容Range bodyRange = document.getRange();// 替换内容for (Map.Entry<String, Object> entry : contentMap.entrySet()) {bodyRange.replaceText("${" + entry.getKey() + "}", entry.getValue().toString());}//导出到文件try {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();document.write(byteArrayOutputStream);OutputStream outputStream = new FileOutputStream(exportFile);outputStream.write(byteArrayOutputStream.toByteArray());byteArrayOutputStream.close();in.close();outputStream.close();} catch (IOException e) {e.printStackTrace();}}}

2下面来一张模板图片

3 .进行word模板转word以及输出前端下载实现代码

 //3.1替换的值 k,v mapHashMap<String, Object> contentMap = new HashMap<String, Object>();contentMap.put("${date}", this.projectVO.getDate());//3.2 模板路径String fileName = "book.doc";String pathIn =  GboatAppContext.getWebRootPath() +"download" + "/" + fileName;//3.3 生成文件路径    String  exportFile = "进场交易确认书.docx";String pathOut= GboatAppContext.getWebRootPath() + "download" + "/" + exportFile;//执行DocUtil.getBuild(pathIn , contentMap, exportFile);//4这段代码是 页面直接弹出下载生成的文件InputStream inStream = new FileInputStream(pathOut);response.setHeader("Content-Type", "application/octet-stream");// 设置response的编码方式response.setContentType("application/x-msdownload");String headers = request.getHeader("User-Agent").toUpperCase();if (headers.contains("MSIE") || headers.contains("TRIDENT") || headers.contains("EDGE")) {exportFile = URLEncoder.encode(exportFile, "utf-8");// IE下载文件名空格变+号问题exportFile = exportFile.replace("+", "%20");} else {exportFile = new String(exportFile.getBytes("utf-8"), "ISO8859-1");}// 设置附加文件名response.setHeader("Content-Disposition", "attachment;filename=" + exportFile);byte[] b = new byte[512];int len;ServletOutputStream outputStream = response.getOutputStream();while ((len = inStream.read(b)) > 0) {outputStream.write(b, 0, len);}inStream.close();// 将写入到客户端的内存的数据,刷新到磁盘outputStream.flush();outputStream.close();

2 第二种带图片的word模板,只支持 docx的

2.1 工具类word模板工具类

import org.apache.poi.xwpf.usermodel.*;import javax.servlet.http.HttpServletResponse;import java.io.*;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** 通过word模板生成新的word工具类
*/
public class WordUtils {/*** 根据模板生成word* @param path     模板的路径* @param params   需要替换的参数* @param tableList   需要插入的参数* @param fileName 生成word文件的文件名* @param response*/public void getWord(String path, Map<String, Object> params,  String fileName, HttpServletResponse response) throws Exception {File file = new File(path);InputStream is = new FileInputStream(file);CustomXWPFDocument doc = new CustomXWPFDocument(is);this.replaceInPara(doc, params);    //替换文本里面的变量// this.replaceInTable(doc, params, tableList); //替换表格里面的变量//导出到文件try {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();doc.write(byteArrayOutputStream);OutputStream outputStream = new FileOutputStream(fileName);outputStream.write(byteArrayOutputStream.toByteArray());byteArrayOutputStream.close();is.close();outputStream.close();} catch (IOException e) {e.printStackTrace();}}/*** 替换段落里面的变量* @param doc    要替换的文档* @param params 参数*/private void replaceInPara(CustomXWPFDocument doc, Map<String, Object> params) {Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();XWPFParagraph para;while (iterator.hasNext()) {para = iterator.next();this.replaceInPara(para, params, doc);}}/*** 替换段落里面的变量** @param para   要替换的段落* @param params 参数*/private void replaceInPara(XWPFParagraph para, Map<String, Object> params, CustomXWPFDocument doc) {List<XWPFRun> runs;Matcher matcher;if (this.matcher(para.getParagraphText()).find()) {runs = para.getRuns();int start = -1;int end = -1;String str = "";for (int i = 0; i < runs.size(); i++) {XWPFRun run = runs.get(i);String runText = run.toString();if ('$' == runText.charAt(0) && '{' == runText.charAt(1)) {start = i;}if ((start != -1)) {str += runText;}if ('}' == runText.charAt(runText.length() - 1)) {if (start != -1) {end = i;break;}}}for (int i = start; i <= end; i++) {para.removeRun(i);i--;end--;}for (Map.Entry<String, Object> entry : params.entrySet()) {String key = entry.getKey();if (str.indexOf(key) != -1) {Object value = entry.getValue();if (value instanceof String) {str = str.replace(key, value.toString());para.createRun().setText(str, 0);break;} else if (value instanceof Map) {str = str.replace(key, "");Map pic = (Map) value;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 {//int ind = doc.addPicture(byteInputStream,picType);//doc.createPicture(ind, width , height,para);doc.addPictureData(byteInputStream, picType);doc.createPicture(doc.getAllPictures().size() - 1, width, height, para);para.createRun().setText(str, 0);break;} catch (Exception e) {e.printStackTrace();}}}}}}/*** 为表格插入数据,行数不够添加新行** @param table     需要插入数据的表格* @param tableList 插入数据集合*/private static void insertTable(XWPFTable table, List<String[]> tableList) {//创建行,根据需要插入的数据添加新行,不处理表头for (int i = 0; i < tableList.size(); i++) {XWPFTableRow row = table.createRow();}//遍历表格插入数据List<XWPFTableRow> rows = table.getRows();int length = table.getRows().size();for (int i = 1; i < length - 1; i++) {XWPFTableRow newRow = table.getRow(i);List<XWPFTableCell> cells = newRow.getTableCells();for (int j = 0; j < cells.size(); j++) {XWPFTableCell cell = cells.get(j);String s = tableList.get(i - 1)[j];cell.setText(s);}}}/*** 替换表格里面的变量* @param doc    要替换的文档* @param params 参数*/private void replaceInTable(CustomXWPFDocument doc, Map<String, Object> params, List<String[]> tableList) {Iterator<XWPFTable> iterator = doc.getTablesIterator();XWPFTable table;List<XWPFTableRow> rows;List<XWPFTableCell> cells;List<XWPFParagraph> paras;while (iterator.hasNext()) {table = iterator.next();if (table.getRows().size() > 1) {//判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入if (this.matcher(table.getText()).find()) {rows = table.getRows();for (XWPFTableRow row : rows) {cells = row.getTableCells();for (XWPFTableCell cell : cells) {paras = cell.getParagraphs();for (XWPFParagraph para : paras) {this.replaceInPara(para, params, doc);}}}} else {insertTable(table, tableList);  //插入数据}}}}/*** 正则匹配字符串** @param str* @return*/private Matcher matcher(String str) {Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher(str);return matcher;}/*** 根据图片类型,取得对应的图片类型代码** @param picType* @return int*/private static int getPictureType(String picType) {int res = CustomXWPFDocument.PICTURE_TYPE_PICT;if (picType != null) {if (picType.equalsIgnoreCase("png")) {res = CustomXWPFDocument.PICTURE_TYPE_PNG;} else if (picType.equalsIgnoreCase("dib")) {res = CustomXWPFDocument.PICTURE_TYPE_DIB;} else if (picType.equalsIgnoreCase("emf")) {res = CustomXWPFDocument.PICTURE_TYPE_EMF;} else if (picType.equalsIgnoreCase("jpg") || picType.equalsIgnoreCase("jpeg")) {res = CustomXWPFDocument.PICTURE_TYPE_JPEG;} else if (picType.equalsIgnoreCase("wmf")) {res = CustomXWPFDocument.PICTURE_TYPE_WMF;}}return res;}/*** 将输入流中的数据写入字节数组** @param in* @return*/public static byte[] inputStream2ByteArray(InputStream in, boolean isClose) {byte[] byteArray = null;try {int total = in.available();byteArray = new byte[total];in.read(byteArray);} catch (IOException e) {e.printStackTrace();} finally {if (isClose) {try {in.close();} catch (Exception e2) {e2.getStackTrace();}}}return byteArray;}/*** 关闭输入流** @param is*/private void close(InputStream is) {if (is != null) {try {is.close();} catch (IOException e) {e.printStackTrace();}}}/*** 关闭输出流** @param os*/private void close(OutputStream os) {if (os != null) {try {os.close();} catch (IOException e) {e.printStackTrace();}}}}

这个有个问题就是 每一行只能有一个 值被替换 时候表格的那种带图片的模板

4 word转pdf,最后还是找了 使用libreoffice来进行转pdf 这种方式

注,将 word文件利用libreoffice的第三方插件来转换

1代码工具类1

package glodon.govp.cy.utils;
import java.io.File;
import java.io.IOException;/*** 使用libreoffice来进行转pdf*/
public class LibreOffice {public static boolean wordConverterToPdf(String docxPath) throws IOException {File file = new File(docxPath);String path = file.getParent();try {String osName = System.getProperty("os.name");String command = "";if (osName.contains("Windows")) {command = "cmd /c soffice --convert-to pdf  -outdir " + docxPath + " " + path;} else {command = "libreoffice --headless --invisible --convert-to pdf:writer_pdf_Export " + docxPath + " --outdir " + path;System.out.println("命令----------------------"+command+"-----------------------------");}boolean result = CommandExecute.executeLibreOfficeCommand(command);return result;} catch (Exception e) {e.printStackTrace();throw e;}}

2.代码工具类2

package glodon.govp.cy.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** linux或windows命令执行*/
public class CommandExecute {private static Logger logger = LoggerFactory.getLogger(CommandExecute.class);public static void main(String[] args) {// CommandExecute obj = new CommandExecute();//  String domainName = "www.baidu.com";//in mac oxs// String command = "ping " + domainName;//in windows//String command = "ping -n 3 " + domainName;// String output = obj.executeCommand(command);// System.out.println(output);convertOffice2PDF("D:\\11.docx", "D:\\GBP");}public static String executeCommand(String command) {StringBuffer output = new StringBuffer();Process p;InputStreamReader inputStreamReader = null;BufferedReader reader = null;try {p = Runtime.getRuntime().exec(command);p.waitFor();inputStreamReader = new InputStreamReader(p.getInputStream(), "UTF-8");reader = new BufferedReader(inputStreamReader);String line = "";while ((line = reader.readLine()) != null) {output.append(line + "\n");}} catch (IOException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();} finally {IOUtils.closeQuietly(reader);IOUtils.closeQuietly(inputStreamReader);}System.out.println(output.toString());return output.toString();}/*** 执行command指令* @param command* @return*/public static boolean executeLibreOfficeCommand(String command) {logger.info("开始进行转化.......");Process process;// Process可以控制该子进程的执行或获取该子进程的信息try {logger.debug("convertOffice2PDF cmd : {}", command);process = Runtime.getRuntime().exec(command);// exec()方法指示Java虚拟机创建一个子进程执行指定的可执行程序,并返回与该子进程对应的Process对象实例。// 下面两个可以获取输入输出流
//            InputStream errorStream = process.getErrorStream();
//            InputStream inputStream = process.getInputStream();} catch (IOException e) {logger.error(" convertOffice2PDF {} error", command, e);return false;}int exitStatus = 0;try {exitStatus = process.waitFor();// 等待子进程完成再往下执行,返回值是子线程执行完毕的返回值,返回0表示正常结束// 第二种接受返回值的方法int i = process.exitValue(); // 接收执行完毕的返回值logger.debug("i----" + i);} catch (InterruptedException e) {logger.error("InterruptedException  convertOffice2PDF {}", command, e);return false;}if (exitStatus != 0) {logger.error("convertOffice2PDF cmd exitStatus {}", exitStatus);} else {logger.debug("convertOffice2PDF cmd exitStatus {}", exitStatus);}process.destroy(); // 销毁子进程logger.info("转化结束.......");return true;}/*** * soffice --headless --invisible --convert-to pdf:writer_pdf_Export D:/test/fb35e7d25afaf1b5d34f7bdb4f830c8c.doc --outdir D:/testfile2html* * @param srcPath* @param desPath* @return* @throws NullPointerException */public static boolean convertOffice2PDF(String srcPath, String desPath) throws NullPointerException{System.out.println("开始进行转化.....");if(srcPath == null || desPath == null){throw new NullPointerException("转化文件不存在或者路径有问题");}String command = "";String osName = System.getProperty("os.name");if (osName.contains("Windows")) {command = "cmd /c soffice --headless --invisible --convert-to pdf:writer_pdf_Export " + srcPath + " --outdir " + desPath;}System.err.println(command + " : 转化中....");try {Process p = Runtime.getRuntime().exec(command);p.waitFor();return true;} catch (Exception e) {e.printStackTrace();return false;} finally {System.out.println("转化结束...");}}}

3word调用libreoffice工具类实现的转换的代码

 public static void main(String[] args) {try {LibreOffice.wordConverterToPdf("D:\\11.docx");} catch (IOException e) {e.printStackTrace();}}

4.生成word模板2 及word转pdf实现的代码

public void downloadDetailsExcel() {try {// 下载// 组织数据initData();String projectName = this.projectVO.getProjectName().replace(" ", "").trim();String osName = System.getProperty("os.name");String fileName = "book.docx";String pathIn =  GboatAppContext.getWebRootPath() +"download" + "/" + fileName;String exportFile = projectName+"进场交易确认书.docx";//window的if (!osName.contains("Windows")) {//linux的exportFile = "进场交易确认书.docx";}String pathOut= GboatAppContext.getWebRootPath() + "download" + "/" + exportFile;HashMap<String, Object> contentMap = new HashMap<String, Object>();contentMap.put("${date}", this.projectVO.getDate());contentMap.put("${project}", this.projectVO.getProcurementAgenter()+"组织的"+projectName+"(项目编号为:"+this.projectVO.getProjectCode()+")已于"+this.projectVO.getDate()+"在北京市朝阳区公共资源交易平台完成交易。");Map<String,Object> header = new HashMap<String, Object>();header.put("width", 150);header.put("height", 150);header.put("type", "jpg");header.put("content", WordUtils.inputStream2ByteArray(CyAdmissionConfirmationAction.class.getClassLoader().getResourceAsStream("static/gongzhang.jpg"), true));contentMap.put("${picture}",header);//生成wordWordUtils  utils = new WordUtils();utils.getWord(pathIn, contentMap,  pathOut, response);//word转pdfif (!osName.contains("Windows")) {exportFile = "进场交易确认书.docx";pathOut= GboatAppContext.getWebRootPath() + "download" + "/" + exportFile;}LibreOffice.wordConverterToPdf(pathOut);//输出到页面文件流if (!osName.contains("Windows")) {exportFile = "进场交易确认书.pdf";pathOut= GboatAppContext.getWebRootPath() + "download" + "/" + exportFile;}InputStream inStream = new FileInputStream(pathOut);response.setHeader("Content-Type", "application/octet-stream");// 设置response的编码方式response.setContentType("application/x-msdownload");String headers = request.getHeader("User-Agent").toUpperCase();if (headers.contains("MSIE") || headers.contains("TRIDENT") || headers.contains("EDGE")) {exportFile = URLEncoder.encode(exportFile, "utf-8");// IE下载文件名空格变+号问题exportFile = exportFile.replace("+", "%20");} else {exportFile = new String(exportFile.getBytes("utf-8"), "ISO8859-1");}// 设置附加文件名response.setHeader("Content-Disposition", "attachment;filename=" + exportFile);byte[] b = new byte[512];int len;ServletOutputStream outputStream = response.getOutputStream();while ((len = inStream.read(b)) > 0) {outputStream.write(b, 0, len);}inStream.close();// 将写入到客户端的内存的数据,刷新到磁盘outputStream.flush();outputStream.close();//更新评价状态 是否下载了进场交易确认书ArrivalEvaluation arrivalEvaluation =confirmationBusiness.getArrivalEvaluationByProjectId(projectId);if(null != arrivalEvaluation && !"2".equals(arrivalEvaluation.getDownloadStatus())){arrivalEvaluation.setDownloadStatus("2");confirmationBusiness.update(arrivalEvaluation);}} catch (Exception e) {GboatAppContext.output(JsonResult.createFailure(e.getMessage()));}}

使用libreoffice来进行转pdf 这种方式需要安装的软件

可以参考以下的连接 ;转
链接: [https://blog.csdn.net/eclothy/article/details/84938807]

最后付一下maven依赖:是word模板的

<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.9</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.15</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-scratchpad</artifactId><version>3.9</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.4</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version></dependency><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.2</version></dependency>

当报错时 Error: source file could not be loaded

解决时,应该 在执行语句上加上版本号
libreoffice --headless --invisible --convert-to pdf:writer_pdf_Export " + docxPath + " --outdir " + path;

用着这一方式可以加载到文件
libreoffice6.1 --headless --invisible --convert-to pdf:writer_pdf_Export " + docxPath + " --outdir " + path;

关于最近word模板以及word转pdf的总结相关推荐

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

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

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

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

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

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

  4. C#根据word模板生成word表格报表文档

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

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

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

  6. Java 使用word模板创建word文档报告教程

    上面是java 利用word模板生成的一个word报告文档,利用的是第三方类库Poi-tl 是实现的. poi-tl是一个基于Apache POI的Word模板引擎,也是一个免费开源的Java类库,你 ...

  7. JAVA实现模板word文档导入,Java依据word模板生成word文档之后台解析和实现及部分代码(一)...

    Java根据word模板生成word文档之后台解析和实现及部分代码(一) 后台主要工作是解析XML定义的标签文件,并获取到数据集,放入到Map中,然后调用Jacob.jar中提供的相关方法来实现替换. ...

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

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

  9. poi-tl,根据word模板导出word(表格行循环,表格无表头的情况)

    最近项目里要做一个根据客户提供的word模板导出word的功能,方法有很多,比如easyPoi(对word的支持并不是很好),freeMark(太麻烦不想研究),以及poi-tl, 最后研究了半天发现 ...

最新文章

  1. Exchage 2007 Client Application Functions(2) -- 如何收取邮件
  2. 《英语语法新思维初级教程》学习笔记(一)名词短语
  3. 【Paddy】数据库监控系列(一) - 监控理念
  4. 为何大公司看起来都那么糟?
  5. Entity Framework系列之DataBase First
  6. javafx2_JavaFX 2 GameTutorial第5部分
  7. Java 中的自举类,到底是什么?
  8. 蓝桥杯 入门训练 圆的面积
  9. 基于Android设备的 Kali Linux渗透测试教程(内部资料)
  10. java 信鸽demo_腾讯信鸽推送Java服务端
  11. html 页面文字不能复制粘贴,网页无法复制文字怎么办
  12. 你的颜值打几分?——基于tensorflow实现人脸打分模型
  13. Colab 快速上传数据集方法
  14. linux硬盘ro改为rw,RO,RW,ZI 和scatter file详解(转载)
  15. allegro 走线切换层_PCB 18种特殊走线的画法与技巧
  16. 设计模式汇总,对应Android系统源码举例,保你一次看个够
  17. 产业分析:股权激励市场实践
  18. mapping.xml POJO的映射文件
  19. Mac 重命名快捷键
  20. [转载]中国文明网:为青少年“防沉迷”汇聚合力

热门文章

  1. html语言div怎么使用,什么是div标签?HTML中div标签怎么使用?
  2. mv单位是什么意思_ayawawa经常说的pu MV是什么意思 怎么mv是什么意思算
  3. 荣耀x10和荣耀20pro哪个好?参数配置对比介绍
  4. 详解ZStack Cloud v4.0:自研VPC网络模型实践指南
  5. 网线,交换机基础命令
  6. 移动互联网感言(董烨/Joven.Dong)
  7. 老旗舰华为能用上鸿蒙吗,千元机也能用鸿蒙!曝荣耀 9X 手机年内全部升级鸿蒙系统...
  8. java计算机毕业设计银创科技有限公司人事信息系统源码+数据库+系统+lw文档+部署
  9. Cadence Vitruoso Layout绘制版图
  10. 让前辈再次激励我不断进步