docx4j创建word文档
2017-12-16 11:13
411 查看
案例.根据模版用docx4j生成doc文档,并将doc文档转成pdf文档再下载下来
1.模版
2.docx4j操作类
5.docx4j需要下载docx4j-3.3.0.jar
1.模版
2.docx4j操作类
package com.hdkj.common.util; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import org.apache.commons.lang.StringUtils; import org.docx4j.XmlUtils; import org.docx4j.jaxb.Context; import org.docx4j.openpackaging.exceptions.Docx4JException; import org.docx4j.openpackaging.packages.WordprocessingMLPackage; import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart; import org.docx4j.wml.Br; import org.docx4j.wml.ContentAccessor; import org.docx4j.wml.ObjectFactory; import org.docx4j.wml.P; import org.docx4j.wml.STBrType; import org.docx4j.wml.Tbl; import org.docx4j.wml.Text; import org.docx4j.wml.Tr; public class Docx4jUtils { private static ObjectFactory factory; private WordprocessingMLPackage template; private String target; /** * @return * */ public void connection(String source, String target) throws Docx4JException, FileNotFoundException { // TODO Auto-generated constructor stub this.template = getTemplate(source); this.target = target; } /** * @param name * @return * @throws Docx4JException * @throws FileNotFoundException */ private static WordprocessingMLPackage getTemplate(String name) throws Docx4JException, FileNotFoundException { WordprocessingMLPackage template = WordprocessingMLPackage.load(new FileInputStream(new File(name))); return template; } /** * @param obj * @param toSearch * @return */ // private static List<Object> getAllElementFromObject(Object obj, Class<?> // toSearch) // { // List<Object> result = new ArrayList<Object>(); // if (obj instanceof JAXBElement) // { // obj = ((JAXBElement<?>) obj).getValue(); // } // // if (obj.getClass().equals(toSearch)) // { // result.add(obj); // } // else if (obj instanceof ContentAccessor) // { // List<?> children = ((ContentAccessor) obj).getContent(); // for (Object child : children) // { // result.addAll(getAllElementFromObject(child, toSearch)); // } // // } // return result; // } // 获取对象元素 private static List<Object> getAllElementFromObject(Object obj, Class<?> toSearch) { List<Object> result = new ArrayList<Object>(); if (obj instanceof JAXBElement) obj = ((JAXBElement<?>) obj).getValue(); if (obj.getClass().equals(toSearch)) result.add(obj); else if (obj instanceof ContentAccessor) { List<?> children = ((ContentAccessor) obj).getContent(); for (Object child : children) { result.addAll(getAllElementFromObject(child, toSearch)); } } return result; } // private void test(Map<String, String> replacements, Map<String, String> // pgReplacements) throws Docx4JException, JAXBException { // // TODO Auto-generated method stub // // //要替换的表格 // // Map<String,String> repl0 = new HashMap<String, String>(); // // repl0.put("[table-index1-name]", "yanglw"); // // repl0.put("[table-index1-bh]", "32"); // // repl0.put("[table-index1-sj]", "chenx"); // // // } public void replaceTable(String[] placeholders, List<Map<String, String>> textToAdd) throws Exception { List<Object> tables = getAllElementFromObject(template.getMainDocumentPart(), Tbl.class); if(tables == null || tables.size() == 0){ throw new Exception("模板文档里没有表格,不能进行表格内容替换!!"); } // 1. find the table Tbl tempTable = getTemplateTable(tables, placeholders[0]); if(tempTable == null){ throw new Exception("模板文档里没有表格占位符" + placeholders[0] + ",请检查模板是否正确!!"); } List<Object> rows = getAllElementFromObject(tempTable, Tr.class); // // first row is header, second row is content // if (rows.size() == 2) { // // this is our template row // Tr templateRow = (Tr) rows.get(1); // // for (Map<String, String> replacements : textToAdd) { // // 2 and 3 are done in this method // addRowToTable(tempTable, templateRow, replacements); // } // // // 4. remove the template row // tempTable.getContent().remove(templateRow); // } // 我们现在的模板里面是个很复杂的表格, 首先我们要找到 模板行, 就是第一列是[NO] // 一行一行的遍历, 找包含[NO]的Text Tr templateRow = null; outterLoop: for (int rowIndex = 0; rowIndex < rows.size(); rowIndex++) { Tr row = (Tr) rows.get(rowIndex); // 找到表格里面的所有Text对象 List<?> textElements = getAllElementFromObject(row, Text.class); for (Object text : textElements) { Text textElement = (Text) text; if (textElement.getValue() != null && textElement.getValue().equals(placeholders[0])) { templateRow = row; //placeholders[0]是包含几个元素的数组,为什么可以相等? break outterLoop; } } } if (templateRow == null) { System.out.println("没有找到模板行, 请检查"); } for (Map<String, String> replacements : textToAdd) { // 2 and 3 are done in this method // 原先的这个方法是在表格的最后新增行, 但我们的模板里, 要添加数据的位置不是在最后 // addRowToTable(tempTable, templateRow, replacements); insertRowToTable(tempTable, templateRow, replacements); // 替换字段 } // 4. remove the template row tempTable.getContent().remove(templateRow); } // 获取表格对象 private static Tbl getTemplateTable(List<Object> tables, String templateKey) throws Docx4JException, JAXBException { for (Iterator<Object> iterator = tables.iterator(); iterator.hasNext();) { Object tbl = iterator.next(); // 找到表格里面的所有Text对象 List<?> textElements = getAllElementFromObject(tbl, Text.class); for (Object text : textElements) { Text textElement = (Text) text; if (textElement.getValue() != null && textElement.getValue().equals(templateKey)) return (Tbl) tbl; } } return null; } // 增加表格 private static void addRowToTable(Tbl reviewtable, Tr templateRow, Map<String, String> replacements) { Tr workingRow = (Tr) XmlUtils.deepCopy(templateRow); List<?> textElements = getAllElementFromObject(workingRow, Text.class); for (Object object : textElements) { Text text = (Text) object; String replacementValue = (String) replacements.get(text.getValue()); if (replacementValue != null) text.setValue(replacementValue); } reviewtable.getContent().add(workingRow); } // 插入表格 private static void insertRowToTable(Tbl reviewtable, Tr templateRow, Map<String, String> replacements) { Tr workingRow = (Tr) XmlUtils.deepCopy(templateRow); List<?> textElements = getAllElementFromObject(workingRow, Text.class); for (Object object : textElements) { Text text = (Text) object; String replacementValue = (String) replacements.get(text.getValue()); if (replacementValue != null) text.setValue(replacementValue); } int templateIndex = reviewtable.getContent().indexOf(templateRow); reviewtable.getContent().add(templateIndex, workingRow); } public void processPgTexts(Map<String, String> pgReplacements) { // TODO Auto-generated method stub // paragraph for (Map.Entry<String, String> entry : pgReplacements.entrySet()) { String placeholder = entry.getKey(); String textToAdd = (String) entry.getValue(); replaceParagraph(placeholder, textToAdd, template); } } public void processTexts(Map<String, String> replacements) { // TODO Auto-generated method stub // 进行文本占位符替换 for (Map.Entry<String, String> entry : replacements.entrySet()) { String placeholder = entry.getKey(); // 字段 String textToAdd = (String) entry.getValue(); // 实际数据 replacePlaceholder(placeholder, textToAdd, template); // 替换字段 } } public void writeDocxToStream() throws FileNotFoundException, Docx4JException { // connection(source, target); File f = new File(this.target); try { template.save(f); } catch (Docx4JException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private static void replaceParagraph(String placeholder, String textToAdd, WordprocessingMLPackage template) { // 1. get the paragraph List<Object> paragraphs = getAllElementFromObject(template.getMainDocumentPart(), P.class); P toReplace = null; for (Object p : paragraphs) { List<Object> texts = getAllElementFromObject(p, Text.class); for (Object t : texts) { Text content = (Text) t; content.getValue(); if (content.getValue().equals(placeholder)) { toReplace = (P) p; break; } } } // we now have the paragraph that contains our placeholder: toReplace // 2. split into seperate lines String as[] = StringUtils.splitPreserveAllTokens(textToAdd, '\n'); for (int i = 0; i < as.length; i++) { String ptext = as[i]; // 3. copy the found paragraph to keep styling correct if (null == toReplace) { // doNothing return; } P copy = (P) XmlUtils.deepCopy(toReplace); // replace the text elements from the copy List<?> texts = getAllElementFromObject(copy, Text.class); if (texts.size() > 0) { Text textToReplace = (Text) texts.get(0); textToReplace.setValue(ptext); } // add the paragraph to the document // template.getMainDocumentPart().getContent().add(copy); ((ContentAccessor) toReplace.getParent()).getContent().add(copy); } // 4. remove the original one ((ContentAccessor) toReplace.getParent()).getContent().remove(toReplace);// 将原来文本删除,用了add的方法添加新的段落 // File newFile = new File("C://Users/杨璐玮/Desktop/派工单_模板_处理后pg.doc"); // template.save(newFile); } private static void replacePlaceholder(String placeholder, String textToAdd, WordprocessingMLPackage template) { // TODO Auto-generated method stub List<Object> texts = getAllElementFromObject(template.getMainDocumentPart(), Text.class); for (Object text : texts) { Text textElement = (Text) text; if (textElement.getValue().contains(placeholder)) { String a = textElement.getValue().toString().replace(placeholder, textToAdd); textElement.setValue(a); } } // File newFile = new File("C://Users/杨璐玮/Desktop/派工单_模板_处理后text.doc"); // try { // template.save(newFile); // } catch (Docx4JException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } } // // public static Map getYWData() // { // Map<String, Object> map = new HashMap<String, Object>(); // map.put("[text-no]", "0001"); // map.put("[text-date]", "2016/8/19"); // // return map; // } /** * 向文档添加一个换行符 */ public void addPageBreak() { factory = Context.getWmlObjectFactory(); this.template.getMainDocumentPart().addParagraphOfText("Hello Word!"); MainDocumentPart documentPart = this.template.getMainDocumentPart(); Br breakObj = new Br(); breakObj.setType(STBrType.PAGE); P paragraph = factory.createP(); paragraph.getContent().add(breakObj); documentPart.getJaxbElement().getBody().getContent().add(paragraph); } }3.doc转pdf类
package com.hdkj.common.util; import java.io.File; import java.io.IOException; import java.util.Date; import com.jacob.activeX.ActiveXComponent; import com.jacob.com.Dispatch; import com.jacob.com.Variant; public class Word2PdfUtil { static final int wdDoNotSaveChanges = 0;// 不保存待定的更改。 static final int wdFormatPDF = 17;// word转PDF 格式 // public static void main(String[] args) throws IOException { // String source1 = "d:\\aaa.docx"; // String target1 = "d:\\"+new Date()+".pdf"; // Word2PdfUtil pdf = new Word2PdfUtil(); // pdf.word2pdf(source1, target1); // } public static boolean word2pdf(String source, String target) { System.out.println("Word转PDF开始启动..."); long start = System.currentTimeMillis(); ActiveXComponent app = null; try { app = new ActiveXComponent("Word.Application"); app.setProperty("Visible", false); Dispatch docs = app.getProperty("Documents").toDispatch(); System.out.println("打开文档:" + source); Dispatch doc = Dispatch.call(docs, "Open", source, false, true).toDispatch(); System.out.println("转换文档到PDF:" + target); File tofile = new File(target); if (tofile.exists()) { tofile.delete(); } Dispatch.call(doc, "SaveAs", target, wdFormatPDF); Dispatch.call(doc, "Close", false); long end = System.currentTimeMillis(); System.out.println("转换完成,用时:" + (end - start) + "ms"); return true; } catch (Exception e) { System.out.println("Word转PDF出错:" + e.getMessage()); return false; } finally { if (app != null) { app.invoke("Quit", wdDoNotSaveChanges); } } } }4.调用方法如下
/** * 打印采购供货单 * @param request * @param response */ @RequestMapping(params = "exportWord") public void exportWord(HttpServletRequest request, HttpServletResponse response){ try { String[] Ids = request.getParameterValues("Ids"); String[] IdArray=Ids[0].split(","); //项目定义号 String PURCHASE_SUPPLY_NO=request.getParameter("PURCHASE_SUPPLY_NO"); Docx4jUtils testText = new Docx4jUtils(); String source =""; //1.连接模板 String realPath = request.getSession().getServletContext().getRealPath("\\") ;// 文件的硬盘真实路径 source=realPath+"WEB-INF\\classes\\com\\hdkj\\template\\采购供货单.docx"; //创建导出地址 String target = "C:\\export" ;// 文件的硬盘真实路径 //创建相应目录 File dir = new File(target); if(!dir.exists()){ dir.mkdirs(); } target="C:\\export\\采购供货单_"+PURCHASE_SUPPLY_NO+".docx"; String target2 = "C:\\export\\采购供货单_"+PURCHASE_SUPPLY_NO+".pdf"; Word2PdfUtil pdf = new Word2PdfUtil(); testText.connection(source,target); //2.替换字段 Map<String, String> replacements = new HashMap<String, String>(); Map map=this.tPurchaseSupplyService.getDataBySupplyNo(PURCHASE_SUPPLY_NO); String sgdw=map.get("contract_cxdwms")==null?"":map.get("contract_cxdwms").toString(); String mf=map.get("supplier_name")==null?"":map.get("supplier_name").toString(); String htbh=map.get("contrac_bh")==null?"":map.get("contrac_bh").toString(); String xxjg=map.get("zfpzj")==null?"0":map.get("zfpzj").toString(); replacements.put("[bh]", PURCHASE_SUPPLY_NO); replacements.put("[sgdw]", sgdw); replacements.put("[mf]", mf); replacements.put("[htbh]", htbh); replacements.put("[xxjg1]", xxjg); replacements.put("[xxjg2]", xxjg); //大写金额 String dxje=MoneyUtil.toChinese(xxjg); replacements.put("[dxjg1]", dxje); replacements.put("[dxjg2]", dxje); testText. processTexts(replacements); Map<String,String> repl1; List<Map<String,String>> maplist=new ArrayList(); if(IdArray.length>0){ for(int i=0;i<IdArray.length;i++){ String id=IdArray[i]; Map maptemp=this.tPurchaseSupplyService.getData(id); String xh=maptemp.get("xh").toString(); //合同执行单位名称 String xmdw=maptemp.get("contract_cxdwms")==null?"0":maptemp.get("contract_cxdwms").toString(); //单体工程名称 String xmmc=maptemp.get("monimer_project_name")==null?"0":maptemp.get("monimer_project_name").toString(); //货物名称 String hwmc=maptemp.get("material_description").toString(); //规格/型号 String gg=""; String sl=maptemp.get("cgsl").toString(); //单位 String dw=maptemp.get("jldw").toString(); //含税单价 String hsdj=maptemp.get("zfpdj").toString(); //含税总价 String hszj=maptemp.get("zfpzj").toString(); //交货时间 String jhsj=maptemp.get("delivery_date").toString(); //交货地点 String delivery_place=maptemp.get("delivery_place").toString(); //交货方式 String delivery_mode=maptemp.get("delivery_mode").toString(); repl1 = new HashMap<String, String>(); repl1.put("[xh]", xh); repl1.put("[xmdw]", xmdw); repl1.put("[xmmc]", xmmc); repl1.put("[hwmc]", hwmc); repl1.put("[gg]", gg); repl1.put("[sl]", sl); repl1.put("[dw]", dw); repl1.put("[hsdj]", hsdj); repl1.put("[hszj]", hszj); repl1.put("[jhsj]", jhsj); repl1.put("[ddjfs]", delivery_place+","+delivery_mode); maplist.add(repl1); } testText.replaceTable(new String[]{"[xh]","[xmdw]","[xmmc]","[hwmc]","[gg]","[sl]","[dw]","[hsdj]","[hszj]","[jhsj]","[ddjfs]"}, maplist); } /* //4.替换表格 多个表格时需要重复写 Map<String,String> repl1 = new HashMap<String, String>(); repl1.put("[sp]", "1"); repl1.put("[spnr]", "枪机"); Map<String,String> repl2 = new HashMap<String, String>(); repl2.put("[sp]", "2"); repl2.put("[spnr]", "枪机2"); Map<String,String> repl3 = new HashMap<String, String>(); repl3.put("[sp]", "3"); repl3.put("[spnr]", "枪机3"); testText.replaceTable(new String[]{"[sp]","[spnr]"}, Arrays.asList(repl1,repl2,repl3)); */ //5.生成新的doc文件 testText.writeDocxToStream(); //6.生成新的pdf文件 pdf.word2pdf(target, target2); //7.下载 File file = new File(target2); if(file != null){ // 以流的形式下载文件。 InputStream fis = new BufferedInputStream(new FileInputStream(file)); byte[] buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); // 清空response response.reset(); // 设置response的Header, 汉字要转义 String fileNameEncoded="采购供货单_"+PURCHASE_SUPPLY_NO+".pdf"; fileNameEncoded = new String(fileNameEncoded.getBytes(), "ISO-8859-1"); response.addHeader("Content-Disposition", "attachment;filename=" + fileNameEncoded); response.addHeader("Content-Length", "" + file.length()); OutputStream toClient = new BufferedOutputStream(response.getOutputStream()); response.setContentType("application/octet-stream"); toClient.write(buffer); toClient.flush(); toClient.close(); } response.flushBuffer(); // JSONObject succ = new JSONObject(); // succ.put("success", true); // succ.put("message", "请在桌面上查看导出的文件!"); // ServletUtils.printJsonData(succ.toString(), response); } catch (Exception e) { e.printStackTrace(); logger.warn(e.getMessage()); JSONObject error = new JSONObject(); error.put("success", false); error.put("message", e.getMessage()); ServletUtils.printJsonData(error.toString(), response); } }
5.docx4j需要下载docx4j-3.3.0.jar
相关文章推荐
- 使用docx4j编程式地创建复杂的Word(.docx)文档
- 使用Docx4j创建word文档
- 使用Docx4j创建word文档
- 使用docx4j编程式地创建复杂的Word(.docx)文档
- 使用Docx4j创建word文档
- 使用docx4j编程式地创建复杂的Word(.docx)文档
- C#对Word文档的创建、插入表格、设置样式等操作实例
- 直接用php创建word文档代码(系统无需安装word软件)
- 向Docx4j生成的word文档添加图片和布局--第一部分
- 解决用Aspose.Words,在word文档中创建表格的实现方法
- 如何利用代理创建WORD文档
- 使用C#创建Word文档
- 直接用php创建word文档
- PHP创建word文档的方法(平台无关)
- php创建读取 word.doc文档
- Word组件Spire.Doc 教程:在word文档中创建书签
- 为word文档创建文档结构图的的步骤
- 使用 Word 2007 和 Visual Basic 2005 自动创建数据丰富的业务文档
- Docx4J操作word文档
- C#程序通过模板自动创建Word文档.doc