700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 使用poi根据模版生成word文档并转换成PDF文件

使用poi根据模版生成word文档并转换成PDF文件

时间:2019-01-24 15:56:44

相关推荐

使用poi根据模版生成word文档并转换成PDF文件

一、首先制作word模版(这里需要注意的是文件后缀是docx不能是doc),${xxxx}是一会要替换的内容

关于为何必须是docx后缀可以看这篇文章/ct-csu/p/8178932.html

二、添加poi所需要的jar包文件,我用的maven对jar包进行管理

三、由于poi自身bug,会出现图片无法显示问题,这里需要自定义一个类继承XWPFDocument类,接下来使用的都是我们自己创建的这个类来操作word对象,这个

类对XWPFDocument进行了继承,所以不用担心会有什么问题

package com.newdo.base;import java.io.IOException;import java.io.InputStream;import org.apache.poi.openxml4j.opc.OPCPackage;import org.apache.poi.xwpf.usermodel.XWPFDocument;/*** word 导出工具类*/public class CustomXWPFDocument extends XWPFDocument{public CustomXWPFDocument(InputStream in) throws IOException {super(in);}public CustomXWPFDocument() {super();}public CustomXWPFDocument(OPCPackage pkg) throws IOException {super(pkg);}}

四、接下来就是导出word的工具类了

package com.newdo.base;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.ByteArrayInputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import .URLEncoder;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.regex.Matcher;import java.util.regex.Pattern;import javax.servlet.http.HttpServletResponse;import org.apache.poi.xwpf.usermodel.XWPFParagraph;import org.apache.poi.xwpf.usermodel.XWPFRun;import org.apache.poi.xwpf.usermodel.XWPFTable;import org.apache.poi.xwpf.usermodel.XWPFTableCell;import org.apache.poi.xwpf.usermodel.XWPFTableRow;import com.jacob.activeX.ActiveXComponent;import .ComThread;import .Dispatch;/*** word 导出工具类*/public class WordUtils {/*** 用于判断导出的word是否转pdf*/public static int judgment = 0;public WordUtils() {judgment = 0;}/*** 根据模板生成word* * @param path模板的路径* @param params 需要替换的参数* @param tableList 需要插入的参数* @param fileName 生成word文件的文件名* @param response*/public void getWord(String path, Map<String, Object> params, List<String[]> tableList, String fileName,HttpServletResponse response) throws Exception {String saveRoute = path.substring(0, path.indexOf("\\"));File file = new File(path);InputStream is = new FileInputStream(file);CustomXWPFDocument doc = new CustomXWPFDocument(is);this.replaceInPara(doc, params); // 替换文本里面的变量this.replaceInTable(doc, params, tableList); // 替换表格里面的变量OutputStream os = null;if (judgment == 0) {fileName = .URLDecoder.decode(fileName, "UTF-8");os = new FileOutputStream(saveRoute + "\\word\\" + fileName);doc.write(os);String pdf = fileName.substring(0, fileName.lastIndexOf(".")) + ".pdf"; // 截掉wToPdfChange(saveRoute + "\\word\\" + fileName, saveRoute + "\\word\\" + pdf);try {System.out.println("========================pdf下载开始========================");// path是指欲下载的文件的路径。file = new File(saveRoute + "\\word\\" + pdf);// 取得文件名。String filename = URLEncoder.encode(file.getName(), "utf-8");// 取得文件的后缀名。String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();// 以流的形式下载文件。is = new BufferedInputStream(new FileInputStream(saveRoute + "\\word\\" + pdf));byte[] buffer = new byte[is.available()];is.read(buffer);// 清空responseresponse.reset();// 设置response的Headerresponse.addHeader("Content-Disposition", "attachment;filename=" + filename);response.addHeader("Content-Length", "" + file.length());os = new BufferedOutputStream(response.getOutputStream());response.setContentType("application/octet-stream");os.write(buffer);os.flush();System.out.println("========================pdf下载结束========================");} catch (IOException ex) {ex.printStackTrace();}} else {//os = response.getOutputStream();fileName = .URLDecoder.decode(fileName, "UTF-8");os = new FileOutputStream(saveRoute + "\\word\\" + fileName);response.setHeader("Content-Disposition", "attachment; filename=" + fileName);doc.write(os);judgment = 0;}this.close(os);this.close(is);}/*** word 转 pdf* * @param wordFile word 的路径 word 的路径* @param pdfFile pdf 的路径*/public static void wToPdfChange(String wordFile, String pdfFile) {ActiveXComponent app = null;Dispatch document = null;System.out.println("========================开始转换========================");try {// 打开wordSystem.out.println("开始打开word");app = new ActiveXComponent("Word.Application");// 获得word中所有打开的文档Dispatch documents = app.getProperty("Documents").toDispatch();System.out.println("打开文件: " + wordFile);// 打开文档document = Dispatch.call(documents, "Open", wordFile, false, true).toDispatch();// 如果文件存在的话,不会覆盖,会直接报错,所以我们需要判断文件是否存在File target = new File(pdfFile);if (target.exists()) {target.delete();}System.out.println("另存为: " + pdfFile);Dispatch.call(document, "SaveAs", pdfFile, 17);} catch (Exception e) {System.out.println("转换失败" + e.getMessage());} finally {// 关闭office//app.invoke("Quit", 0);if (document != null) {// 关闭文档Dispatch.call(document, "Close", false);}if (app != null) {app.invoke("Quit", 0);}// 获取系统类型String osName = System.getProperty("os.name");// 判断是系统类型if (osName.toLowerCase().startsWith("win")) {System.out.println(osName);// window系统String killCmd = "taskkill /f /im wps.exe";String killCmd1 = "taskkill /f /im wpscenter.exe";Process p;try {p = Runtime.getRuntime().exec(killCmd);p = Runtime.getRuntime().exec(killCmd1);int runnngStatus = p.waitFor();System.out.println("已杀" + runnngStatus);} catch (IOException e) {e.printStackTrace();System.out.println("转换失败" + e.getMessage());} catch (InterruptedException e) {e.printStackTrace();System.out.println("转换失败" + e.getMessage());}}}System.out.println("========================转换结束========================");}/*** 替换段落里面的变量* * @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 runsIndex = "";String str = "";for (int i = 0; i < runs.size(); i++) {XWPFRun run = runs.get(i);String runText = run.toString().trim();if (!runText.equals("") && (runText.indexOf("${")!=-1 || runText.equals("}"))){if ('$' == runText.charAt(0) && '{' == runText.charAt(1)) {start = i;runsIndex += i+",";}if ((start != -1)) {str += runText;}if ('}' == runText.charAt(runText.length() - 1)) {if (start != -1) {end = i;for (int k = start; k <= end; k++) {para.removeRun(k);k--;end--;}}}}}//for (int i = start; i <= end; i++) {//para.removeRun(i);//i--;//end--;//}int doInt = 0;String[] runsIns = runsIndex.split(",");for (int k=0;k<runsIns.length;k++){if (!"".equals(str)) {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());if (((String) str).indexOf("\r") > 0) {// 设置换行String[] text = str.toString().split("\r");para.removeRun(0);for (int f = 0; f < text.length; f++) {if (f == 0) {// 此处不缩进因为word模板已经缩进了。para.createRun().setText(text[f].trim());} else {para.createRun().addCarriageReturn();// 硬回车// 注意:wps换行首行缩进是三个空格符,office要的话可以用// run.addTab();缩进或者四个空格符para.createRun().setText(text[f]);}}} else {//para.createRun().setText((String) value);int num = 0;if (doInt==0){num = CFunc.ToInt(runsIns[k]);}else{num = CFunc.ToInt(runsIns[k])+doInt;}para.insertNewRun(num).setText((String) value);doInt++;}// 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);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();//System.out.println("------------>" + table.getRows().size());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 = pile("\\$\\{(.+?)\\}", 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*/public void close(InputStream is) {if (is != null) {try {is.close();} catch (IOException e) {e.printStackTrace();}}}/*** 关闭输出流** @param os*/public void close(OutputStream os) {if (os != null) {try {os.close();} catch (IOException e) {e.printStackTrace();}}}}

五、word转pdf文件我们需要用到一个jacob.jar(下载地址在文章下面 )的一个包,将该jar包放入项目中的resources文件下的lib中

maven中引入本地jar包

同时需要将jacob中的dll文件放到自己的jdk环境中,将 dll 文件拷贝到 C:\Program Files\Java\jdk1.8.0_191\jre\bin (这是我自己的jdk位置)下,或者拷贝到当前项目运行的 jdk 的目录下的 jre/bin 目录下

这里的文件多少位(×64或×86)是根据自己的电脑来的

完成以上操作word才能正常转换为pdf文件

六、最后就是进行测试了,我是用的是springboot框架,这里放出测试代码

@Overridepublic void contractPrintDetail(HttpServletRequest request, HttpServletResponse response, Map<String, Object> mapArgu) {//查询出来的数据Map<String,Object> map = contractPrintMapper.mySelect(mapArgu);WordUtils wordUtil = new WordUtils();Map<String, Object> params = new LinkedHashMap<String, Object>();List<String[]> testList = new ArrayList<String[]>();params.put("${DWMC}",map.get("DWMC"));params.put("${DWDZ}",map.get("DWDZ"));params.put("${FDDBR}",map.get("FDDBR"));params.put("${XM}",map.get("XM"));params.put("${XBMC}",map.get("XBMC"));params.put("${LXDH}",map.get("LXDH"));params.put("${JG}",map.get("JG"));params.put("${ZS}",map.get("ZS"));params.put("${SFZHM}",map.get("SFZHM"));params.put("${GWMC}",map.get("GWMC"));try{String path = CFunc.clobToString((Clob) map.get("HTMB"));String name = CFunc.ToString(map.get("XM")) + "_" + CFunc.ToString(map.get("HTLX"))+"合同.docx";String filename = URLEncoder.encode(name, "utf-8");response.setContentType(request.getServletContext().getMimeType(filename));wordUtil.getWord(path, params, testList, filename, response);}catch (Exception e){e.printStackTrace();}

七、最后生成的pdf文档

POI官网:/

Apache POI Word 简易示例文档:/skymozn/blog/3189732

JACOB:/projects/jacob-project/?source=typ_redirect

参考链接:

/duanrantao/p/8682897.html

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