`
53873039oycg
  • 浏览: 824211 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

[简单]docx4j替换模板数据示例

阅读更多

       步骤一:把模板后缀名修改为zip解压

      

     步骤二:打开word/document.xml

     

     步骤三:把所有${不连续的修改为连续,如${1,}修改为${1}

    

    

    

     步骤五:选中解压内容压缩为zip,修改后缀名为docx

    

      

      下面举个实际例子:

      如果数据是静态的

      

                WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new java.io.File(inputfilepath));
		MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
		HashMap<String, String> staticMap = getStaticData();
		// 替换普通变量
		documentPart.variableReplace(staticMap);
		// 保存结果
		saveWordPackage(wordMLPackage, outputfilepath);

    替换完成,后面的东西没必要看了。

    如果内容中有普通表格且表格内容有动态数据,如

      

      层次、民族数据是动态的,保证表格有数据,即打开word/document.xml看到如下内容tc下面只有一个t:

     

 

       参考例子如下:

       

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.xml.bind.JAXBElement;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.docx4j.TraversalUtil;
import org.docx4j.XmlUtils;
import org.docx4j.dml.chart.CTChartSpace;
import org.docx4j.dml.chart.CTNumDataSource;
import org.docx4j.dml.chart.CTNumVal;
import org.docx4j.dml.chart.CTPieChart;
import org.docx4j.dml.chart.CTPieSer;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.DrawingML.Chart;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.openpackaging.parts.relationships.Namespaces;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.wml.Body;
import org.docx4j.wml.Br;
import org.docx4j.wml.ContentAccessor;
import org.docx4j.wml.Document;
import org.docx4j.wml.P;
import org.docx4j.wml.R;
import org.docx4j.wml.Tbl;
import org.docx4j.wml.Tc;
import org.docx4j.wml.TcPr;
import org.docx4j.wml.TcPrInner.VMerge;
import org.docx4j.wml.Text;
import org.docx4j.wml.Tr;
import org.docx4j.wml.TrPr;
import org.junit.Test;

public class Docx4j_替换模板 {
	private String inputfilepath = "E:/test_tmp/0904/test_docx.docx";
	private static final String outputfilepath = "e:/test_tmp/0904/sys_" + System.currentTimeMillis() + ".docx";
	public static org.docx4j.wml.ObjectFactory factory = Context.getWmlObjectFactory();

	@Test
	public void testReplaceTemplateDocx() throws Exception {
		replaceTemplateDocx();
	}

	public void replaceTemplateDocx() throws Exception {
		WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new java.io.File(inputfilepath));
		MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
		HashMap<String, String> staticMap = getStaticData();
		// 替换普通变量
		documentPart.variableReplace(staticMap);

		Document document = (Document) documentPart.getContents();
		Body body = document.getBody();
		MyTblFinder tblFinder = new MyTblFinder();
		new TraversalUtil(body, tblFinder);
		// 替换表格模板第三行数据
		Tbl firstTbl = tblFinder.getTbls().get(0);
		List<Object> trObjList = firstTbl.getContent();
		Tr tr = (Tr) trObjList.get(2);
		replaceTrTotalData(tr, getTotalData());

		int lvlIndex = 3;
		// 替换表格模板第四行数据
		int lvlTotalSize = 4;
		tr = (Tr) trObjList.get(lvlIndex);
		List<String[]> lvDataList = getLvDataList(lvlTotalSize);
		replaceTrData(firstTbl, tr, lvDataList, lvlIndex);

		// 重新获取表格数据
		trObjList = firstTbl.getContent();
		int sexTotalSize = 2;
		// 替换表格模板第五行数据
		tr = (Tr) trObjList.get(lvlIndex + lvlTotalSize);
		List<String[]> sexDataList = getSexDataList(2);
		replaceTrSexData(tr, sexDataList.get(0));
		// 替换表格模板第六行数据
		tr = (Tr) trObjList.get(4 + lvlTotalSize);
		replaceTrSexData(tr, sexDataList.get(1));

		// 替换表格模板第七行数据
		tr = (Tr) trObjList.get(5 + lvlTotalSize);
		int nationTotalSize = 56;
		List<String[]> nationDataList = getNationDataList(nationTotalSize);
		replaceTrData(firstTbl, tr, nationDataList, lvlIndex+lvlTotalSize+sexTotalSize);

		// 合并层次单元格 层次位于第3行
		mergeCellsVertically(firstTbl, 0, lvlIndex, lvlIndex + lvlTotalSize - 1);
		// 合并民族单元格 层次+性别2行
		mergeCellsVertically(firstTbl, 0, lvlIndex + lvlTotalSize + sexTotalSize,
				lvlIndex + lvlTotalSize + sexTotalSize + nationTotalSize - 1);

		// 替换图表数据
		String[] chartArr = getChartData();
		replacePieChartData(wordMLPackage, chartArr);
		// 保存结果
		saveWordPackage(wordMLPackage, outputfilepath);
	}

	/**
	 * 替换图表数据
	 */
	private void replacePieChartData(WordprocessingMLPackage wordMLPackage, String[] chartArr) throws Docx4JException {
		RelationshipsPart rp = wordMLPackage.getMainDocumentPart().getRelationshipsPart();
		Relationship rel = rp.getRelationshipByType(Namespaces.SPREADSHEETML_CHART);
		Chart chart = (Chart) rp.getPart(rel);
		CTChartSpace chartSpace = chart.getContents();
		List<Object> charObjList = chartSpace.getChart().getPlotArea().getAreaChartOrArea3DChartOrLineChart();
		CTPieChart pieChart = (CTPieChart) charObjList.get(0);
		List<CTPieSer> serList = pieChart.getSer();
		CTNumDataSource serVal = serList.get(0).getVal();
		List<CTNumVal> ptList = serVal.getNumRef().getNumCache().getPt();
		ptList.get(0).setV(chartArr[0]);
		ptList.get(1).setV(chartArr[1]);
	}

	/**
	 * 替换tr数据
	 */
	private void replaceTrSexData(Tr tr, String[] dataArr) throws Exception {
		List<Tc> tcList = getTrAllCell(tr);
		Tc tc = null;
		for (int i = 2, iLen = tcList.size(); i < iLen; i++) {
			tc = tcList.get(i);
			replaceTcContent(tc, dataArr[i - 2]);
		}
	}

	/**
	 * 替换tr数据,其他插入
	 */
	private void replaceTrData(Tbl tbl, Tr tr, List<String[]> dataList, int trIndex) throws Exception {
		TrPr trPr = XmlUtils.deepCopy(tr.getTrPr());
		String tcContent = null;
		String[] tcMarshaArr = getTcMarshalStr(tr);
		String[] dataArr = null;
		for (int i = 0, iLen = dataList.size(); i < iLen; i++) {
			dataArr = dataList.get(i);
			Tr newTr = null;
			Tc newTc = null;
			if (i == 0) {
				newTr = tr;
			} else {
				newTr = factory.createTr();
				if (trPr != null) {
					newTr.setTrPr(trPr);
				}
				newTc = factory.createTc();
				newTr.getContent().add(newTc);
			}
			for (int j = 0, jLen = dataArr.length; j < jLen; j++) {
				tcContent = tcMarshaArr[j];
				if (tcContent != null) {
					tcContent = tcContent.replaceAll("(<w:t>)(.*?)(</w:t>)", "<w:t>" + dataArr[j] + "</w:t>");
					newTc = (Tc) XmlUtils.unmarshalString(tcContent);
				} else {
					newTc = factory.createTc();
					setNewTcContent(newTc, dataArr[j]);
				}
				// 新增tr
				if (i != 0) {
					newTr.getContent().add(newTc);
				} else {
					// 替换
					newTr.getContent().set(j + 1, newTc);
				}
			}
			if(i!=0){
				tbl.getContent().add(trIndex+i, newTr);
			}
		}
	}

	/**
	 * 获取单元格字符串
	 */
	private String[] getTcMarshalStr(Tr tr) {
		List<Object> tcObjList = tr.getContent();
		String[] marshaArr = new String[7];
		// 跳过层次
		for (int i = 1, len = tcObjList.size(); i < len; i++) {
			marshaArr[i - 1] = XmlUtils.marshaltoString(tcObjList.get(i), true, false);
		}
		return marshaArr;
	}

	/**
	 * 替换表格合计数据
	 */
	private void replaceTrTotalData(Tr tr, String[] dataArr) {
		List<Object> tcObjList = tr.getContent();
		Tc tc = null;
		// 跳过合计
		for (int i = 2, len = tcObjList.size(); i < len; i++) {
			tc = (Tc) XmlUtils.unwrap(tcObjList.get(i));
			replaceTcContent(tc, dataArr[i - 2]);
		}
	}

	/**
	 * 替换单元格内容
	 */
	private void replaceTcContent(Tc tc, String value) {
		List<Object> rtnList = getAllElementFromObject(tc, Text.class);
		if (rtnList == null || rtnList.size() == 0) {
			return;
		}
		Text textElement = (Text) rtnList.get(0);
		textElement.setValue(value);
	}

	/**
	 * 设置单元格内容
	 * 
	 * @param tc
	 * @param content
	 */
	public static void setNewTcContent(Tc tc, String content) {
		P p = factory.createP();
		tc.getContent().add(p);
		R run = factory.createR();
		p.getContent().add(run);
		if (content != null) {
			String[] contentArr = content.split("\n");
			Text text = factory.createText();
			text.setSpace("preserve");
			text.setValue(contentArr[0]);
			run.getContent().add(text);

			for (int i = 1, len = contentArr.length; i < len; i++) {
				Br br = factory.createBr();
				run.getContent().add(br);// 换行
				text = factory.createText();
				text.setSpace("preserve");
				text.setValue(contentArr[i]);
				run.getContent().add(text);
			}
		}
	}

	/**
	 * @Description: 跨行合并
	 */
	public static void mergeCellsVertically(Tbl tbl, int col, int fromRow, int toRow) {
		if (col < 0 || fromRow < 0 || toRow < 0) {
			return;
		}
		for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
			Tc tc = getTc(tbl, rowIndex, col);
			if (tc == null) {
				break;
			}
			TcPr tcPr = getTcPr(tc);
			VMerge vMerge = tcPr.getVMerge();
			if (vMerge == null) {
				vMerge = factory.createTcPrInnerVMerge();
				tcPr.setVMerge(vMerge);
			}
			if (rowIndex == fromRow) {
				vMerge.setVal("restart");
			} else {
				vMerge.setVal("continue");
			}
		}
	}

	public static TcPr getTcPr(Tc tc) {
		TcPr tcPr = tc.getTcPr();
		if (tcPr == null) {
			tcPr = new TcPr();
			tc.setTcPr(tcPr);
		}
		return tcPr;
	}

	public static Tc getTc(Tbl tbl, int row, int cell) {
		if (row < 0 || cell < 0) {
			return null;
		}
		List<Tr> trList = getTblAllTr(tbl);
		if (row >= trList.size()) {
			return null;
		}
		List<Tc> tcList = getTrAllCell(trList.get(row));
		if (cell >= tcList.size()) {
			return null;
		}
		return tcList.get(cell);
	}

	public static List<Tc> getTrAllCell(Tr tr) {
		List<Object> objList = getAllElementFromObject(tr, Tc.class);
		List<Tc> tcList = new ArrayList<Tc>();
		if (objList == null) {
			return tcList;
		}
		for (Object tcObj : objList) {
			if (tcObj instanceof Tc) {
				Tc objTc = (Tc) tcObj;
				tcList.add(objTc);
			}
		}
		return tcList;
	}

	public static List<Tr> getTblAllTr(Tbl tbl) {
		List<Object> objList = getAllElementFromObject(tbl, Tr.class);
		List<Tr> trList = new ArrayList<Tr>();
		if (objList == null) {
			return trList;
		}
		for (Object obj : objList) {
			if (obj instanceof Tr) {
				Tr tr = (Tr) obj;
				trList.add(tr);
			}
		}
		return trList;
	}

	/**
	 * 按class获取内容
	 */
	public 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;
	}

	/**
	 * 保存文档
	 */
	public static void saveWordPackage(WordprocessingMLPackage wordPackage, String filePath) throws Exception {
		wordPackage.save(new File(filePath));
	}

	/**
	 * 获取图表数据
	 */
	private String[] getChartData() {
		int[] intArr = new int[] { RandomUtils.nextInt(1, 99), 0 };
		intArr[1] = 100 - intArr[0];
		return new String[] { Integer.toString(intArr[0]), Integer.toString(intArr[1]) };
	}

	/**
	 * 获取民族数据
	 */
	private List<String[]> getNationDataList(int total) {
		List<String[]> dataList = new ArrayList<String[]>();
		for (int i = 0; i < total; i++) {
			dataList.add(
					new String[] { "民族_" + i, RandomStringUtils.randomNumeric(2), RandomStringUtils.randomNumeric(2),
							RandomStringUtils.randomNumeric(2), RandomStringUtils.randomNumeric(2),
							RandomStringUtils.randomNumeric(2), RandomStringUtils.randomNumeric(2) });
		}
		return dataList;
	}

	/**
	 * 获取性别数据
	 */
	private List<String[]> getSexDataList(int total) {
		List<String[]> dataList = new ArrayList<String[]>();
		// 男
		dataList.add(new String[] { RandomStringUtils.randomNumeric(2), RandomStringUtils.randomNumeric(2),
				RandomStringUtils.randomNumeric(2), RandomStringUtils.randomNumeric(2),
				RandomStringUtils.randomNumeric(2), RandomStringUtils.randomNumeric(2) });
		// 女
		dataList.add(new String[] { RandomStringUtils.randomNumeric(2), RandomStringUtils.randomNumeric(2),
				RandomStringUtils.randomNumeric(2), RandomStringUtils.randomNumeric(2),
				RandomStringUtils.randomNumeric(2), RandomStringUtils.randomNumeric(2) });
		return dataList;
	}

	/**
	 * 获取层次数据
	 */
	private List<String[]> getLvDataList(int total) {
		List<String[]> dataList = new ArrayList<String[]>();
		for (int i = 0; i < total; i++) {
			dataList.add(
					new String[] { "本科_" + i, RandomStringUtils.randomNumeric(2), RandomStringUtils.randomNumeric(2),
							RandomStringUtils.randomNumeric(2), RandomStringUtils.randomNumeric(2),
							RandomStringUtils.randomNumeric(2), RandomStringUtils.randomNumeric(2) });
		}
		return dataList;
	}

	/**
	 * 获取合计数据
	 */
	private String[] getTotalData() {
		return new String[] { "2000", "44.4", "2500", "55.5", "500", "11.11" };
	}

	/**
	 * 获取静态数据
	 */
	private HashMap<String, String> getStaticData() {
		HashMap<String, String> dataMap = new HashMap<String, String>();
		dataMap.put("Pg1-1", "2016");
		dataMap.put("Pg1-2", "11");
		dataMap.put("Pg1-02", "18");
		dataMap.put("Pg1-3", "2000");
		dataMap.put("Pg1-4", "500");
		dataMap.put("Pg1-5", "1500");
		dataMap.put("Pg1-6", "900");
		dataMap.put("Pg1-7", "600");
		dataMap.put("Pg1-8", "2015");
		dataMap.put("Pg1-9", "1000");
		dataMap.put("Pg1-10", "10");
		dataMap.put("Pg1-11", "1");
		dataMap.put("Pg1-12", "5");
		dataMap.put("Pg1-13", "3");
		dataMap.put("Pg1-14", "4");
		dataMap.put("Tb1-24", "25");
		dataMap.put("Tb1-44", "45");
		dataMap.put("Tb1-54", "30");
		dataMap.put("Pg2-1", "1200");
		dataMap.put("Tb1-64", "60");
		dataMap.put("Pg2-2", "800");
		dataMap.put("Tb1-74", "40");
		dataMap.put("Pg2-3", "0.66");
		return dataMap;
	}
}

   

import java.util.ArrayList;
import java.util.List;

import org.docx4j.TraversalUtil.CallbackImpl;
import org.docx4j.wml.Tbl;

public class MyTblFinder extends CallbackImpl {
	public List<Tbl> tblList = new ArrayList<Tbl>();

	public List<Object> apply(Object o) {
		if (o instanceof Tbl) {
			tblList.add((Tbl) o);
		}
		return null;
	}

	public boolean shouldTraverse(Object o) {
		return !(o instanceof Tbl);
	}

	public List<Tbl> getTbls() {
		return tblList;
	}
}

    结果为:

    

     全文完。

  • 大小: 3.5 KB
  • 大小: 12.4 KB
  • 大小: 23.6 KB
  • 大小: 12.8 KB
  • 大小: 10.3 KB
  • 大小: 26.2 KB
  • 大小: 5.7 KB
  • 大小: 27.8 KB
分享到:
评论
1 楼 haiyangyiba 2018-10-09  
感谢分享,写得挺好的,如果有模板文件参考就更好了

相关推荐

    docx4j 替换文本

    NULL 博文链接:https://01jiangwei01.iteye.com/blog/2123628

    docx4j根据书签替换word中的内容

    这是一段用docx4j根据书签替换word文档中的内容的代码,研究了一段时间,而且下了很多东西,希望有点用

    docx4j操作word

    docx4j操作word,主要使用docx4j对word进行操作,比如chart图表、标签替换、目录等。

    DOCX4J jar包

    docx4j 用的jar包,docx4j学习网址:http://www.docx4java.org/trac/docx4j

    docx4j及其依赖包

    docx4j支持操作后缀.docx得word文档,替换书签,获取文档内容,稳定资源

    最新 docx4j-master

    最新 docx4j-master最新 docx4j-master最新 docx4j-master最新 docx4j-master最新 docx4j-master最新 docx4j-master最新 docx4j-master最新 docx4j-master最新 docx4j-master最新 docx4j-master最新 docx4j-master...

    用docx4j操作word书签,在word书签中插入文本

    用docx4j,jar出去word书签,在word书签中插入文本 源码可以通过以下链接查看: https://github.com/xulp-mzl/xlp-core https://github.com/xulp-mzl/xlp-third ...实例: public static void main(String[] args) ...

    docx4j项目(包括jar包、javadoc文档、源码及示例)

    资源中包含docx4j项目的jar包(及主要依赖Jar)、javadoc、源码和示例等,因为花费挺大力气整理出来,所以定了2分,如果您有需要而缺少CSDN下载,请留言或发短消息索取.... 另外,请关注我的博客,其中有些对docx4j...

    docx4j生成word文档

    最近在做一个出卷系统,需要通过试卷模板从数据库中抽取题目,然后按照模板的样式生成完整的试卷,包括试卷格式的排版和图片的写入。这是用docx4j生成word文档。里面包括完整代码和所需jar包。

    word模板替换,插入图片

    jacob 替换word图片,rtf模板文件字符替换,字符替换成图片,docx4j操作word,itext,poi读取文档图片,条码生成插入文档等... 包和需要的文件都在里面,解压直接可以导入运行

    docx4j 动态生成表格 (一 )

    NULL 博文链接:https://01jiangwei01.iteye.com/blog/2123504

    java实现多个docx文档合并(基于docx4j)

    java实现word的合并,jdk版本1.7,直接导入eclipse中即可。基于docx4j3.3.3实现。内含所有jar包,MargeDoc中含有主方法

    docx4j api

    docx4j api 帮助文档 word导出必备 学习必备

    docx4j项目(javadoc文档、源码及示例)

    docx4j是Java操作office2007+中的Word、Excel、PPT的开源项目,其主要针对WordXML同时也可以处理Excel和PPT,比POI要强大很多

    docx4j相关资料

    docx4j相关资料

    使用docx4j将图片签名插入到word中书签位置

    压缩包里包含了必要的docx4j.jar、commons-io-1.4.jar、slf4j-api-1.7.17.jar、freemrkker.jar等架包,导入到到项目后重新build path,然后运行InsertPicture.java文件,(ps:文件的参数替换成自己本地的),便可以...

    程序员简历模板.docx程序员简历模板.docx

    程序员简历模板.docx程序员简历模板.docx程序员简历模板.docx程序员简历模板.docx程序员简历模板.docx程序员简历模板.docx程序员简历模板.docx程序员简历模板.docx 程序员简历模板.docx程序员简历模板.docx程序员...

    docx4j操作word2007

    docx4j操作word2007

Global site tag (gtag.js) - Google Analytics