工作中,我们时常会遇到一些操作文件的操作,比如在线生成合同模板,上传/下载/解析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. gradle 构建测试

    以后决不能再犯此类低级错误

  2. [leetcode]301. Remove Invalid Parentheses 去除无效括号

    Remove the minimum number of invalid parentheses in order to make the input string valid. Return all ...

  3. Condition Variable使用及其Thread Cancellation线程取消

    条件变量Condition Variable的一般用法: 唤醒用法: struct { pthread_mutex_t mutex; pthread_cond_t cond; //whatever v ...

  4. CF 990 Educational Codeforces Round 45

    既然补了就简单记录一下. 感觉还算有一点营养. 官方题解传送门:点我 A Commentary Boxes 对拆掉$n \mod m$个和新建$m - (n \mod m)$求个最小. #includ ...

  5. 企业招聘:UX设计师需要满足他们哪些期望?

    以下内容由Mockplus团队翻译整理,仅供学习交流,Mockplus是更快更简单的原型设计工具.   为了确定2017年最有价值的用户体验技能和特质,我特地参考了150多份工作要求.最后,得出了以下 ...

  6. 这样的UX设计师简历,HR分分钟给你来电话

    BLS调查显示,软件开发和IT,用户体验设计,产品经理和项目管理这三个职位在未来有非凡的发展前景.其中,用户体验设计师是目前最有需求的创意产业工作之一.10年里就业增长率高达22.1%,工作岗位数3, ...

  7. qt学习(三) qt布局

    使用横向与竖向.网格三种布局嵌套使用后可以组合出很复杂的界面. 这里向大家推荐这篇博客 http://www.cnblogs.com/Bonker/p/3454956.html 我这里使用布局做了一个 ...

  8. idea中处理异常的快捷键

    alt+Enter

  9. java 内存 线程 类 vm分析工具

    JMeter.Jconsole.JVMStat

  10. swift -懒加载创建view

     // 只有外界访问到headerView的时候才会去执行闭包, 然后将闭包的返回值赋值给headerView     // 注意: 一定要记住闭包后面需要写上(), 代表执行闭包     //懒加载 ...