700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > docx4j操作word文档之替换模板数据

docx4j操作word文档之替换模板数据

时间:2020-08-24 14:26:01

相关推荐

docx4j操作word文档之替换模板数据

docx4j替换模板数据

docx4j

docx4j是一个开源(ASLv2)Java库,用于创建和操作Microsoft Open XML(Word docx,Powerpoint pptx和Excel xlsx)文件;它类似于Microsoft的OpenXML SDK,但适用于Java。docx4j使用JAXB来创建内存中的对象表示。

示例

1. word中创建占位符

如果我要替换word文档中的动态数据,只需把数据用${xxx}形式标注。

这里可能会存在一个问题:

将.docx文档压缩成.zip文档,再xml文件阅读器打开word/document.xml文件,可以看到有可能出现下图占位符被分隔的问题,这样的话,到时候不能被数据替换。

原因:网上有许多,有的说占位符格式不统一;有的说单词校验问题。

解决方法:我刚开始试了把占位符的格式统一,好像没什么用,然后只能在xml文件里一个一个的改,既累又麻烦!最后,把要写的占位符先写到记事本中,然后再复制到word中,这样就不会被分隔。

2.获取模板以及替换数据

import org.docx4j.model.datastorage.migration.VariablePrepare;import org.docx4j.openpackaging.packages.WordprocessingMLPackage;import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;import java.beans.PropertyDescriptor;import java.io.*;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.text.SimpleDateFormat;import java.util.*;public class Docx4jDemo1 {public static void main(String[] args) {Map<String, String> data = new HashMap<>();data.put("classname", "三年二班");data.put("total", "50");data.put("male", "30");data.put("female", "20");data.put("name", "小明");data.put("sex", "男");data.put("age", "10");data.put("phone", "13888888888");data.put("address", "中国");data.put("email", "xiaoming@");try {replaceData(data);} catch (Exception e) {e.printStackTrace();}}/*** 加载模板并替换数据** @param data* @return* @throws Exception*/public static void replaceData(Map<String, String> data) throws Exception {final String TEMPLATE_NAME = "D://1.docx";InputStream templateInputStream = new FileInputStream(TEMPLATE_NAME);//加载模板文件并创建WordprocessingMLPackage对象WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(templateInputStream);MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();VariablePrepare.prepare(wordMLPackage);documentPart.variableReplace(data);OutputStream os = new FileOutputStream(new File("D://test.docx"));ByteArrayOutputStream outputStream = new ByteArrayOutputStream();wordMLPackage.save(outputStream);outputStream.writeTo(os);os.close();outputStream.close();templateInputStream.close();}/*** 如果从数据库查出来的是不同对象集合,那么该方法直接把对象的属性和值直接存为Map* 比如示例中可以是两个对象,ClassInfo(className,total,male,female)、student(name,sex,...)* 前提是模板中的占位符一定要和对象的属性名一一对应* @param objlist* @return* @throws Exception*/public HashMap<String, String> toMap(List<Object> objlist) throws Exception {HashMap<String, String> variables = new HashMap<>();String value = "";if (objlist == null && objlist.isEmpty()) {return null;} else {for (Object obj : objlist) {Field[] fields = null;fields = obj.getClass().getDeclaredFields();//删除字段数组里的serialVersionUIDfor (int i = 0; i < fields.length; i++) {fields[i].setAccessible(true);if (fields[i].getName().equals("serialVersionUID")) {fields[i] = fields[fields.length - 1];fields = Arrays.copyOf(fields, fields.length - 1);break;}}//遍历数组,获取属性名及属性值for (Field field : fields) {field.setAccessible(true);String fieldName = field.getName();//如果属性类型是Dateif (field.getGenericType().toString().equals("class java.util.Date")) {PropertyDescriptor pd = new PropertyDescriptor(fieldName, obj.getClass());Method getMethod = pd.getReadMethod();Date date = (Date) getMethod.invoke(obj);value = (date == null) ? "" : new SimpleDateFormat("yyyy-MM-dd").format(date);} else if (field.getGenericType().toString().equals("class java.lang.Integer")) {//如果属性类型是IntegerPropertyDescriptor pd = new PropertyDescriptor(fieldName, obj.getClass());Method getMethod = pd.getReadMethod();Object object = getMethod.invoke(obj);value = (object == null) ? String.valueOf(0) : object.toString();} else if (field.getGenericType().toString().equals("class java.lang.Double")) {//如果属性类型是DoublePropertyDescriptor pd = new PropertyDescriptor(fieldName, obj.getClass());Method getMethod = pd.getReadMethod();Object object = getMethod.invoke(obj);value = (object == null) ? String.valueOf(0.0) : object.toString();} else {PropertyDescriptor pd = new PropertyDescriptor(fieldName, obj.getClass());Method getMethod = pd.getReadMethod();Object object = getMethod.invoke(obj);value = (object == null) ? " " : object.toString();}variables.put(fieldName, value);}}return variables;}}}

结果

这些都是一些简单的功能,复杂的后续会有,因为时间关系,只写了这点。这些功能的实现都是前辈们智慧的结晶以及自己的一些探索。有什么不足之处望大家批评指正!感谢大家!

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