工作中,我们时常会遇到一些操作文件的操作,比如在线生成合同模板,上传/下载/解析Excel,doc文档转为pdf等操作。本文就已工作中遇到的在线生成合同为例,简要地介绍一种文档替换写法。

本文目的:给出源文件模板,通过程序操作后,替换模板中的指定内容,从而生成固定模板的文件。

使用场景:生成固定格式的合同信息。

原理:给一个文档模板,需要替换的内容以 $$包含,然后,在代码中给需要替换的字段赋值,生成新的文档。

工具包:poi-ooxml-3.10.jar   自己网上下载

代码:

 package word2pdf;

 import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import org.apache.poi.POIXMLDocument;
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; public class DocWriterTest { public static void searchAndReplace(String srcPath, String destPath, Map<String, String> map) {
try {
XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(srcPath));
/**
* 替换段落中的指定文字
*/
Iterator<XWPFParagraph> itPara = document.getParagraphsIterator();
while (itPara.hasNext()) {
XWPFParagraph paragraph = (XWPFParagraph) itPara.next();
Set<String> set = map.keySet();
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
String key = iterator.next().trim();
List<XWPFRun> run = paragraph.getRuns();
int runSize = run.size();
for (int i = 0; i < runSize; i++) {
String text = run.get(i).getText(0);
System.out.println("++++++text++++++:" + text);
for (Entry<String, String> e : map.entrySet()) {
if (text != null && text.contains(e.getKey())) {
text = text.replace(e.getKey(), e.getValue());
System.out.println("++++++text222222222++++++:" + text);
run.get(i).setText(text, 0);
}
}
}
}
} /**
* 替换表格中的指定文字
*/
Iterator<XWPFTable> itTable = document.getTablesIterator();
while (itTable.hasNext()) {
XWPFTable table = (XWPFTable) itTable.next();
int count = table.getNumberOfRows();
for (int i = 0; i < count; i++) {
XWPFTableRow row = table.getRow(i);
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
for (XWPFParagraph p : cell.getParagraphs()) {
for (XWPFRun r : p.getRuns()) {
String text = r.getText(0);
for (Entry<String, String> e : map.entrySet()) {
if (text != null && text.contains(e.getKey())) {
text = text.replace(e.getKey(), e.getValue());
r.setText(text, 0);
}
}
}
} }
}
}
FileOutputStream outStream = null;
outStream = new FileOutputStream(destPath);
document.write(outStream);
outStream.close();
} catch (Exception e) {
e.printStackTrace();
} } public static void main(String[] args) throws Exception {
Map<String, String> map = new HashMap<String, String>();
map.put("$name$", "coco");
map.put("$sex$", "女");
map.put("work", "Java开发");
String srcPath = "E:\\cocoxu\\test_mode\\sourcefile.docx";
String destPath = "E:\\cocoxu\\test_mode\\destfile.docx";
searchAndReplace(srcPath, destPath, map);
}
}

调试时遇到的报错:

1.

java.lang.IllegalStateException: Zip File is closed
at org.apache.poi.openxml4j.util.ZipFileZipEntrySource.getEntries(ZipFileZipEntrySource.java:45)
at org.apache.poi.openxml4j.opc.ZipPackage.getPartsImpl(ZipPackage.java:182)
at org.apache.poi.openxml4j.opc.OPCPackage.getParts(OPCPackage.java:665)
at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:226)
at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:186)
at org.apache.poi.POIXMLDocument.openPackage(POIXMLDocument.java:67)
at word2pdf.DocWriterTest.searchAndReplace(DocWriterTest.java:23)
at word2pdf.DocWriterTest.main(DocWriterTest.java:93)

此类错看似是zip文件被关闭,其实不然。其实是由于文档路径写错,找不到文件导致的。

String srcPath = "E:\\cocoxu\\\test_mode\\sourcefile.docx";

2、没有生产想要的文件:

sourcefile.docx内容:

目的是用代码中的内容,替换文档中的内容,但是我们第一次得到的确实这样的:

在代码中打印日志,可以看到,word文档中的$name$被跨行分开了:

本来是一行的东西,为什么代码执行操作的时候会被分成三行呢?这个就是doc文档操作的问题啦 ,

方法一:操作源文档,对文档中所有拼写语法不合规范的都忽略

方法二:创建一个新文档,在纯英文格式下拼写字段,然后复制带源文件中,即可。

最终得到的目的问题内容:

至此,我们用java操作文档的案例就结束了,实际工作中也可以模仿此类代码去生成哦。

Java中常用到的文件操作那些事(一)——替换doc文档模板,生成真实合同案例的更多相关文章

  1. Java中常用到的文件操作那些事(二)——使用POI解析Excel的两种常用方式对比

    最近生产环境有个老项目一直内存报警,不时的还出现内存泄漏,导致需要重启服务器,已经严重影响正常服务了.获取生成dump文件后,使用MAT工具进行分析,发现是其中有个Excel文件上传功能时,经常会导致 ...

  2. JAVA中让Swagger产出更加符合我们诉求的描述文档,按需决定显示或者隐藏指定内容

    大家好,又见面啦. 在前一篇文档<JAVA中自定义扩展Swagger的能力,自动生成参数取值含义说明,提升开发效率>中,我们探讨了如何通过自定义注解的方式扩展swagger的能力让Swag ...

  3. Java中常用IO流之文件流的基本使用姿势

    所谓的 IO 即 Input(输入)/Output(输出) ,当软件与外部资源(例如:网络,数据库,磁盘文件)交互的时候,就会用到 IO 操作.而在IO操作中,最常用的一种方式就是流,也被称为IO流. ...

  4. Java中常用的操作PDF的类库

    iText iText是一个能够快速产生PDF文件的java类库.iText的java类对于那些要产生包含文本,表格,图形的只读文档是很有用的.它的类库尤其与java Servlet有很好的给合.使用 ...

  5. java中常用的工具类(三)

    继续分享java中常用的一些工具类.前两篇的文章中有人评论使用Apache 的lang包和IO包,或者Google的Guava库.后续的我会加上的!谢谢支持IT江湖 一.连接数据库的综合类       ...

  6. java中常用的工具类(二)

    下面继续分享java中常用的一些工具类,希望给大家带来帮助! 1.FtpUtil           Java   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...

  7. java中常用的工具类(一)

    我们java程序员在开发项目的是常常会用到一些工具类.今天我汇总了一下java中常用的工具方法.大家可以在项目中使用.可以收藏!加入IT江湖官方群:383126909 我们一起成长 一.String工 ...

  8. Java高级特性 第2节 java中常用的实用类(1)

    一.Java API Java API即Java应用程序编程接口,他是运行库的集合,预先定义了一些接口和类,程序员可以直接调用:此外也特指API的说明文档,也称帮助文档. Java中常用的包: jav ...

  9. Java中常用的设计模式代码与理解

    Java中常用的设计模式代码与理解 一.单例模式 1.饿汉式 (太饿了,类加载的时候就创建实例) /** * 饿汉式单例模式 */ public class HungrySingleInstance ...

随机推荐

  1. 磁盘512n,512e,4k原生磁盘的区别和操作系统支持

    磁盘按照物理扇区大小的不同分为三种512byte原生扇区硬盘(512n),4KB扇区仿真512byte(512E)磁盘,4kB扇区原生磁盘. 首先说物理扇区,扇区是硬盘上最小的读写单位,这个是硬盘决定 ...

  2. gd库已打开,验证码不显示

    ob_start(); ob_clean();

  3. vue 使用axios 数据请求第三方插件的使用

    axios 基于http客户端的promise,面向浏览器和nodejs 特色 浏览器端发起XMLHttpRequests请求 node端发起http请求 支持Promise API 监听请求和返回 ...

  4. 声音处理(Cool Edit)

    平直化处理 上升半音

  5. 测试用数据库表设计和SessionFactory

    本篇为struts-2.5.2和spring-3.2.0以及hibernate-4.2.21的整合开篇. 一.测试的数据库表. 用户.角色和权限关系表.数据库是Mysql5.6.为了考虑到一些特殊数据 ...

  6. 看懂gc日志

    使用的是:+PrintGCDetails -XX:+PrintGCTimeStamps 输出的日志格式: [Times: user=0.03 sys=0.00, real=0.01 secs] 363 ...

  7. 介绍 ASP.NET Identity - ASP.NET 应用程序的成员身份认证系统

    ASP.NET Identity 是构建 ASP.NET web 应用程序的一种新的身份认证系统.ASP.NET Identity 可以让您的应用程序拥有登录功能,并可以轻松地自定义登录用户的相关数据 ...

  8. Xshell传输文件

    用rz,sz命令在xshell传输文件 很好用,然后有时候想在windows和linux上传或下载某个文件,其实有个很简单的方法就是rz,sz 首先你的Ubuntu需要安装rz.sz(如果没有安装请执 ...

  9. solr特点九:word(分词)

    在Solr中配置中文分词IKAnalyzer 1.在配置文件schema.xml(位置{SOLR_HOME}/config/下),配置信息如下: <!-- IKAnalyzer 中文分词--&g ...

  10. 如何在TortoiseGit中使用ssh-keygen生成的key

    再windows 用TortoiseGit 时,git clone 项目时 提示 "Couldn't load this key (OpenSSH SSH-2 private key),如下 ...