poi导出word2003(动态数据,不用模板,且生成word能再次导入)
一、场景需求:
有个项目需要将某个题库里面的题目导出word2003,之前框架里面没有导出word2003的工具类。倒是见过导出txt,excel的,但是word的没有。
二、技术选型
网上找了一通,导出word的有几个技术方案,不过对于word2003版导出的例子比较少。
程序导出word思路(2003版的)
1、利用freemarker来做,xml定义doc的模版,程序动态获取数据,塞值。这个没去试了,时间不够。
2、利用itext来做,能导出来,据说格式是rtf,能用word打开。不过poi导入这个生成的word不支持,poi导入底层源码有对rtf格式做校验,会抛异常。看过源码,但没有试过用itext来做。
/*** Takens an InputStream, verifies that it's not RTF, builds a* POIFSFileSystem from it, and returns that.*/public static POIFSFileSystem verifyAndBuildPOIFS(InputStream istream) throws IOException {// Open a PushbackInputStream, so we can peek at the first few bytesPushbackInputStream pis = new PushbackInputStream(istream,6);byte[] first6 = new byte[6];pis.read(first6);// Does it start with {\rtf ? If so, it's really RTFif(first6[0] == '{' && first6[1] == '\\' && first6[2] == 'r'&& first6[3] == 't' && first6[4] == 'f') {throw new IllegalArgumentException("The document is really a RTF file");}// OK, so it's not RTF// Open a POIFSFileSystem on the (pushed back) streampis.unread(first6);return new POIFSFileSystem(pis);}
3、利用poi来做,poi操作word2003,api和demo极少,如果能用07版word的,建议用07,网上07版的例子比较多,也能用07版api自己操作创建段落,页码,页面。本来项目要求03版的。
由于项目要求支持导出word,也能将导出的word再次导入到题库里面,因此选用了poi作为03版word导出。(项目导入word也是用poi)
三、遇到的问题
1、poi本身对word的支持度就不高,官网的poi导出word的demo少得可怜。Apache官网自行去搜api吧。
2、用poi导出word,大多数用模板来做,用个标记语言在程序中和对应的word版本中,程序里面替换。这篇博客有写这个模板替换的
3、项目要求的是动态的数据,题目里面有不同题型,还有子题,用模板的方式显然不行。
为此,想对着api,研究一番,不过项目时间紧,赶着上线。和老大沟通过,老大也知道poi对word的支持比较差,demo和api都比较少。不过他觉得既然能导入,应该也是能导出的。
只能自己硬着头皮搞——老大也没有搞过这个。一开始想着程序拼装好动态数据,拼成一个html页面,用poi将html转成word。是成功了。但是生成的word通过poi再次导入,报数组越界之类的。明明用poi导出,再poi导入还是有问题。估计是html的word版丢失了一些真正word需要的标记符号之类。
卡在这里了。
继续试试api,忽然想起看到api有个range.insertBefore(String text)。这个可能有机会突破。正是这个api,成为了解决问题的关键。
最后解决办法:
poi生成word,先读取一个空白模版doc进内存,用该doc对象的range对象上面提到的方法,插入内容,然后将该range用输出流写入到另外一个已存在的空白word文档文件。ok,能导出word,这个导出的word也能通过poi导入。
通过空白文档的word对象,设置动态数据到该word对象(这里不会将动态数据写入到空白文档的文件当中,仅仅是在内存中的),然后再将该有数据的word对象持久化到另外一个word文件里面。这样导出的word也能通过poi导进程序当中。
String filePath = "xxx要导出的word.doc";
String wordContent = "动态数据";try {File doc = new File(filePath) ;if(null == doc || !doc.exists()){doc.createNewFile() ;}String realPathFile = "空白的WORD(填充数据所用).doc";//这个空白word需要手动自己创建一个wordFileInputStream in = new FileInputStream(realPathFile);HWPFDocument hwpfDocument = new HWPFDocument(in);Range range = hwpfDocument.getRange();//获取整个空白的word的文档对象range.insertBefore(wordContent);//插入数据ByteArrayOutputStream ostream = null;ostream = new ByteArrayOutputStream();hwpfDocument.write(ostream);FileOutputStream fos = new FileOutputStream(doc);fos.write(ostream.toByteArray());} catch (Exception e) {e.printStackTrace(); }
不过,生成的word样式还是有些问题。每一行的开头有时候会对不齐,隔了大概一个空白字符。这里无法设置样式。不知道有木有朋友也是这样做。欢迎交流~
动态数据当中是用\r\n和\r作回车和换行的。这里也有一个坑,windos和linux的回车、换行是不相同的。
在此,参考了一些资源,谢谢技术分享:
http://blog.csdn.net/lmb55/article/details/64519658
幸好,最终还是做出来了。用了两天不到的时间。
poi导出word2003(动态数据,不用模板,且生成word能再次导入)相关推荐
- poi导出Excel文件下载数据
poi导出Excel文件下载数据 poi上传Excel文件批量的添加数据 : https://blog.csdn.net/kangshifu007/article/details/103149764 ...
- java 动态导出excel表单 无模板本地生成
java 动态导出excel表单 无模板本地生成 这里使用的是alibaba的公共类excelWriter,注意在pom文件中要引入easyExcel的依赖 public void exportExc ...
- 使用POI导出百万级数据到excel的解决方案
使用POI导出百万级数据到excel的解决方案 参考文章: (1)使用POI导出百万级数据到excel的解决方案 (2)https://www.cnblogs.com/hxun/p/11419006. ...
- Beetl 模板引擎生成word以及excel总结
Beetl Java模板引擎生成word excel 之前项目中使用freemarker和POI进行word以及excel的模板导出,在使用的过程中为了解决一些小问题,意外的接触了Beetl这款模板生 ...
- Java使用ftl模板文件生成Word,以及Word转换图片或Pdf工具类
Java使用ftl模板文件生成Word 一.写在前面 最近在项目中使用打印功能,发现这个功能我已经写过多次了,下面这个文章的发步日期在2020年,不得不感慨时间之快啊. https://blog.cs ...
- 【收藏】Python利用Excel+模板批量生成word文件
Python利用Excel+模板批量生成word文件 最近帮朋友批量生成小区业主物业费未缴的律师函.朋友那有物业那边的表格数据,包括楼栋-房间号.业主姓名.欠费日期.欠款金额等信息.目的是需要将这些表 ...
- poi导出excel,不使用模板的
poi导出excel,基于模板的比较简单,这个列是动态的,所已选择不基于模板的,相对复杂些,要设置样式.包括:设置列宽.设置字体.设置边框 package com.urthink.jxsh.util; ...
- POI导出Excel遇到数据量大该如何解决
最近在使用Java POI导出Excel,使用的是XSSFWorkbook ,遇到数据量超过10w的话程序会爆内存溢出的错误,将XSSFWorkbook 换成SXSSFWorkbook 即可 SXSS ...
- JAVA POI 导出EXCEL时,EXCEL模板中的公式无效问题
JAVA POI 出力EXCEL时,EXCEL模板中的公式无效问题 工作中遇到一个问题. EXCEL模板有两个sheet,画面内容要导出到第二个sheet中,第一个sheet设置公式,读取第二个she ...
最新文章
- 学 Win32 汇编[12]: PTR、OFFSET、ADDR、THIS
- leetcode算法题--K 个一组翻转链表
- 旅行商问题的n种解法
- php mysql切换版本5.7_phpstudy里升级mysql版本到5.7
- C/C++网络编程工作笔记0004---socket()函数详解
- Linux监控平台(zabbix监控介绍,安装zabbix,解决忘记admin密码)
- XSS攻击---不得不防的网站安全漏洞
- 读书笔记-穿越计算机的迷雾
- linux查询hba卡驱动版本,Linux下查看HBA卡的驱动版本和WWPN
- 批量创建文件夹的方法
- python在条件表达式中不允许使用_在条件表达式中不允许使用赋值运算符 = ,会提示语法错误。...
- 在桌面为计算机程序创建快捷方式,什么是快捷方式,电脑快捷方式有什么用?...
- CocosCreator downlevelIteration 允许迭代器进行迭代
- matlab解简单数学规划(线性,非线性,整数规划)
- 服务器装系统步骤图解win7,win7安装系统图解教程
- HBuilderX连接苹果手机iPhone预览移动端页面
- uniApp小程序转快应用
- android 银联插件,Android版添加phonegap-银联支付插件教程
- 浅谈Linux下各种压缩 解压命令和压缩比率对比
- isolar bsw配置工具的基本配置CanIf