版权声明:本文为HaiyuKing原创文章,转载请注明出处!

前言

这个是《PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】》的扩展,上一篇是根据doc模板生成doc文件,这个是根据docx模板生成docx文件。

注意:目前只能java生成,集成到Android项目中,运行报错【暂时未解决】:

Process: com.why.project.poidocxdemo, PID: 13762java.lang.NoClassDefFoundError: Failed resolution of: Ljavax/xml/stream/XMLEventFactory;at org.apache.poi.openxml4j.opc.internal.marshallers.PackagePropertiesMarshaller.<clinit>(PackagePropertiesMarshaller.java:41)at org.apache.poi.openxml4j.opc.OPCPackage.<init>(OPCPackage.java:140)at org.apache.poi.openxml4j.opc.ZipPackage.<init>(ZipPackage.java:103)at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:298)at org.apache.poi.ooxml.util.PackageHelper.open(PackageHelper.java:37)at org.apache.poi.xwpf.usermodel.XWPFDocument.<init>(XWPFDocument.java:142)

前期准备

参考《PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】》

区别在于,模板的占位有所不用【docx模板文件不需要$符号】:

代码分析

参考《PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】》

使用步骤

一、项目组织结构图

注意事项:

1、  导入类文件后需要change包名以及重新import R文件路径

2、  Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

二、导入步骤

1、将poi相关jar文件导入项目中【Demo采用的是module方式】

引用jar文件参考《【Android Studio安装部署系列】十七、Android studio引用第三方库、jar、so、arr文件》

注意:

解析docx文件,需要引用下面的jar文件:

  • poi-4.0.0.jar
  • poi-ooxml-4.0.0.jar
  • poi-ooxml-schemas-4.0.0.jar
  • ooxml-lib目录下的curvesapi-1.05.jar、xmlbeans-3.0.1.jar
  • lib目录下的commons-collections4-4.2.jar
  • 下载的commons-compress-1.18.jar

commons-compress-1.18.jar下载地址:http://commons.apache.org/proper/commons-compress/download_compress.cgi

2、将制作的模板文件复制到D:/temp目录下

3、将PoiUtils.java文件复制到项目中

package com.why.main;import org.apache.poi.xwpf.usermodel.XWPFDocument;
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 java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;public class PoiUtils {//测试public static void main(String[] args) {String templetDocPath = "D:/temp/请假单模板1.docx";String targetDocPath = "D:/temp/请假单1.docx";Map<String, Object> dataMap = new HashMap<String, Object>();dataMap.put("writeDate", "2018年10月14日");dataMap.put("name", "HaiyuKing");dataMap.put("dept", "移动开发组");dataMap.put("leaveType", "☑倒休 √年假 ✔事假 ☐病假 ☐婚假 ☐产假 ☐其他");dataMap.put("leaveReason", "倒休一天。");dataMap.put("leaveStartDate", "2018年10月14日上午");dataMap.put("leaveEndDate", "2018年10月14日下午");dataMap.put("leaveDay", "1");dataMap.put("leaveLeader", "同意");dataMap.put("leaveDeptLeaderImg", "同意!");PoiUtils.writeToDocx(templetDocPath,targetDocPath,dataMap);try {PoiUtils.readDocx(targetDocPath);} catch (Exception e) {// TODO Auto-generated catch block
            e.printStackTrace();}}/*** 通过XWPFDocument对内容进行访问。对于XWPF文档而言,用这种方式进行读操作更佳。* @throws Exception*/public static void readDocx(String templetDocPath) throws Exception {InputStream is = new FileInputStream(templetDocPath);XWPFDocument doc = new XWPFDocument(is);List<XWPFParagraph> paras = doc.getParagraphs();for (XWPFParagraph para : paras) {//当前段落的属性System.out.println("para=="+para.getText());}//获取文档中所有的表格List<XWPFTable> tables = doc.getTables();List<XWPFTableRow> rows;List<XWPFTableCell> cells;for (XWPFTable table : tables) {//获取表格对应的行rows = table.getRows();for (XWPFTableRow row : rows) {//获取行对应的单元格cells = row.getTableCells();for (XWPFTableCell cell : cells) {System.out.println("cell=="+cell.getText());;}}}if (is != null) {try {is.close();} catch (IOException e) {e.printStackTrace();}}}/*** 生成一个docx文件* @param templetDocPath  模板文件的完整路径* @param targetDocPath 生成的目标文件的完整路径* @param dataMap 替换的数据*/public static void writeToDocx(String templetDocPath, String targetDocPath, Map<String,Object> dataMap){try{//得到模板doc文件的HWPFDocument对象InputStream in = new FileInputStream(templetDocPath);writeToDocx(in,targetDocPath,dataMap);}catch(IOException e){e.printStackTrace();}}/*** 生成一个docx文件,主要用于直接读取asset目录下的模板文件,不用先复制到sd卡中* @param templetDocInStream  模板文件的InputStream* @param targetDocPath 生成的目标文件的完整路径* @param dataMap 替换的数据*/public static void writeToDocx(InputStream templetDocInStream, String targetDocPath, Map<String,Object> dataMap){try{//得到模板doc文件的HWPFDocument对象XWPFDocument HDocx = new XWPFDocument(templetDocInStream);//替换段落里面的变量
            replaceInPara(HDocx, dataMap);  //替换表格里面的变量
            replaceInTable(HDocx, dataMap);  //写到另一个文件中OutputStream os = new FileOutputStream(targetDocPath);  //把doc输出到输出流中
            HDocx.write(os);os.close();templetDocInStream.close();}catch(IOException e){e.printStackTrace();}catch(Exception e){e.printStackTrace();}}/** * 替换段落里面的变量 * @param doc 要替换的文档 * @param params 参数 */  private static void replaceInPara(XWPFDocument doc, Map<String, Object> params) {  Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();  XWPFParagraph para;  while (iterator.hasNext()) {  para = iterator.next();  replaceInPara(para, params);  }  }/*** 替换段落里面的变量* @param para 要替换的段落* @param params 参数*/private static void replaceInPara(XWPFParagraph para, Map<String, Object> params) {List<XWPFRun> runs;System.out.println("para.getParagraphText()=="+para.getParagraphText());runs = para.getRuns();for (int i=0; i<runs.size(); i++) {XWPFRun run = runs.get(i);String runText = run.toString();System.out.println("runText=="+runText);// 替换文本内容,将自定义的$xxx$替换成实际文本for(Map.Entry<String, Object> entry : params.entrySet()){runText = runText.replace(entry.getKey(), entry.getValue()+"");//直接调用XWPFRun的setText()方法设置文本时,在底层会重新创建一个XWPFRun,把文本附加在当前文本后面,//所以我们不能直接设值,需要先删除当前run,然后再自己手动插入一个新的run。
                para.removeRun(i);para.insertNewRun(i).setText(runText);}}}/** * 替换表格里面的变量 * @param doc 要替换的文档 * @param params 参数 */  private static void replaceInTable(XWPFDocument doc, Map<String, Object> params) {  Iterator<XWPFTable> iterator = doc.getTablesIterator();  XWPFTable table;  List<XWPFTableRow> rows;  List<XWPFTableCell> cells;  List<XWPFParagraph> paras;  while (iterator.hasNext()) {  table = iterator.next();  rows = table.getRows();  for (XWPFTableRow row : rows) {  cells = row.getTableCells();  for (XWPFTableCell cell : cells) {  paras = cell.getParagraphs();  for (XWPFParagraph para : paras) {  replaceInPara(para, params);  }  }  }  }  }  }

PoiUtils.java

4、运行

5、效果【生成的docx文件有问题,之前的样式全失效了】

混淆配置

暂无

参考资料

Android使用ApachePOI组件读写Worddoc和docx文件

Android 下使用 Poi 读取高版本excel

Java:封装POI实现word的docx文件的简单模板功能

使用POI读写word docx文件

POI操作word2007(docx)文件的文本和图片

项目demo下载地址

链接:https://pan.baidu.com/s/165hpn3kZssxVvHIF9RNtkQ 提取码:3mmj

转载于:https://www.cnblogs.com/whycxb/p/9796659.html

PoiDocxDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0),目前只能java生成】...相关推荐

  1. android 生成多个表单,Android根据word模板文档将表单数据生成word文档的方案整理...

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 尝试的方案包括以下几种: freemarker 只能在java项目上运行,无法在Android项目上运行: poi 解析doc文件可 ...

  2. 将图片和表单数据变为word 文档

    2 ,将图片和表单数据变为word 文档 (承接上一篇)  一开始采用的技术为poi  ,后来发现非常不好行不通 网上poi 将图片和表单数据变为word 文档  技术链接    https://bl ...

  3. C#动态生成Word文档并填充数据(二)

    /* * 1.添加引用->COM->Microsoft Word 11.0 Object Library 本文来源:IT传媒网 原文链接:http://www.cniter.com/tec ...

  4. Java Web项目中使用Freemarker生成Word文档

    Web项目中生成Word文档的操作屡见不鲜,基于Java的解决方案也是很多的,包括使用Jacob.Apache POI.Java2Word.iText等各种方式,其实在从Office 2003开始,就 ...

  5. Java项目中使用Freemarker生成Word文档

    Web项目中生成Word文档的操作屡见不鲜,基于Java的解决方案也是很多的,包括使用Jacob.Apache POI.Java2Word.iText等各种方式,其实在从Office 2003开始,就 ...

  6. [摘]用Java生成Word文档

    开发中隔三叉五的就要用到Word,经常被搞得不胜其烦,不过这次找到了不少好例子,干脆将他们都摘了过来,内容如下: 1. poi是apache的一个项目,不过就算用poi你可能都觉得很烦,不过不要紧,这 ...

  7. 用java生成word文档(转载)

    用java生成word文档 poi是apache的一个项目,不过就算用poi你可能都觉得很烦,不过不要紧,这里提供了更加简单的一个接口给你: 下载经过封装后的poi包: 这个包就是:tm-extrac ...

  8. java web 操作word文档_Java Web项目中使用Freemarker生成Word文档

    Web项目中生成Word文档的操作屡见不鲜.基于Java的解决方式也是非常多的,包含使用Jacob.Apache POI.Java2Word.iText等各种方式,事实上在从Office 2003開始 ...

  9. python实现生成word文档并转为pdf

    python实现生成word文档,格式转为pdf 使用的是python-docx模块,在生成word文档后转为pdf格式是使用的是docx2pdf中的convert(使用convert转换时,要先创建 ...

最新文章

  1. hadoop-07-ntp服务检查
  2. java 打开jsp文件_jsp文件怎么打开(java-web中jsp的理解)
  3. SAP Analytics Cloud和SAP Cloud for Customer的集成
  4. 单选按钮android服务器,android – 如何在radiogroup中将单选按钮设置...
  5. 信息学奥赛一本通(1173:阶乘和)
  6. oracle半角全椒_Oracle全角和半角处理函数
  7. SQL Server中 char与varchar
  8. 搜狗AI,正在抢滩智能手机
  9. win11升级到一半撤销怎么办 windows11升级到一半撤销的解决方法
  10. NetBeans Weeldy News 刊号 # 53 - Apr 23, 2009
  11. MFC中编辑框edit的用法
  12. 企业全面运营管理沙盘模拟心得_企业经营沙盘模拟心得总结
  13. 免费而强大的十款PCB设计软件
  14. Linux——常用工具
  15. 卡方线性趋势检验_趋势性卡方检验专题讨论
  16. FastDFS安装步骤
  17. uniapp——操作成功返回首页
  18. 基于spring boot的婚纱摄影约拍系统
  19. 可以缩放平移的时间刻度尺,方便自定义UI需求。仿萤石云历史录像时间轴
  20. poj pku图论、网络流入门题总结、汇总

热门文章

  1. 解决 PL/SQL Oracle错误:ORA-01033
  2. 最近公共祖先LCA 【专题@AbandonZHANG】
  3. RLE压缩及优化--图片压缩
  4. 一辆汽车让你搞懂springmvc项目结构
  5. 我38岁,从外企技术高管到失业在家,只因为做错了这件事
  6. 快、准、狠!秒杀Excel的报表工具,十分钟教你做好数据填报
  7. 4个超神工作表技巧,还不快学起来!
  8. java对象模型 指令_JVM-Java内存模型-20200217(示例代码)
  9. linux查看java进程_linux中查看java进程
  10. python辅助脚本教程_[Python] 用python做一个游戏辅助脚本,完整思路