docx4j创建word文档

案例.根据模版用docx4j生成doc文档,并将doc文档转成pdf文档再下载下来

1.模版

docx4j创建word文档_第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 getAllElementFromObject(Object obj, Class
	// toSearch)
	// {
	// List result = new ArrayList();
	// 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 getAllElementFromObject(Object obj, Class toSearch) {
		List result = new ArrayList();
		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 replacements, Map
	// pgReplacements) throws Docx4JException, JAXBException {
	// // TODO Auto-generated method stub
	//
	// //要替换的表格
	// // Map repl0 = new HashMap();
	// // repl0.put("[table-index1-name]", "yanglw");
	// // repl0.put("[table-index1-bh]", "32");
	// // repl0.put("[table-index1-sj]", "chenx");
	//
	//
	// }

	public void replaceTable(String[] placeholders, List> textToAdd) throws Exception {
		List 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 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 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 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 tables, String templateKey) throws Docx4JException, JAXBException {
		for (Iterator 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 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 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 pgReplacements) {
		// TODO Auto-generated method stub
		// paragraph
		for (Map.Entry entry : pgReplacements.entrySet()) {
			String placeholder = entry.getKey();
			String textToAdd = (String) entry.getValue();
			replaceParagraph(placeholder, textToAdd, template);
		}
	}

	public void processTexts(Map replacements) {
		// TODO Auto-generated method stub
		// 进行文本占位符替换
		for (Map.Entry 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 paragraphs = getAllElementFromObject(template.getMainDocumentPart(), P.class);

		P toReplace = null;
		for (Object p : paragraphs) {
			List 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 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 map = new HashMap();
	// 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 replacements = new HashMap();
	        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 repl1;
	    	List> maplist=new ArrayList();
	    	if(IdArray.length>0){
	    		for(int i=0;i();
	    			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 repl1 = new HashMap();
			repl1.put("[sp]", "1");
			repl1.put("[spnr]", "枪机");
			Map repl2 = new HashMap();
			repl2.put("[sp]", "2");
			repl2.put("[spnr]", "枪机2");
			Map repl3 = new HashMap();
			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文档)