背景:
先说一下,作者为什么要选择POI来生成报告。之前项目中使用的是jacob,但是偶尔会出现windows错误提示框,word已停止工作,每次都需要手动关闭这个提示框,才能继续生成报告。虽然说是偶尔发生(大概100次中,会发生一次),但是问题还是要解决的。于是作者就尝试杀进程,虽然错误发生的概率降低了,但是还是会偶有发生。查过很多资料,有你提到jacob这种控件本身也有不稳定的问题(问题是这种错误在程序中没法 try catch)。于是乎就换掉jacob啦!之前使用的是word2003,发现poi对word2003的支持还是很弱的。于是乎,就采用word2007啦!这是个大胆的决定,之后还会遇到很多想不到的问题。
作者尝试过 iText,但是好像缺word模板的替换,但是项目中必须要有这个功能;
soa office, 还有国内的xxxx office 是要收费的,于是乎放弃使用了;
docx4j 有篇帖子写的很好,http://blog.csdn.net/zhyh1986/article/details/8766131,但是由于作者先尝试了poi2007,所以没有再尝试使用docx4j。
作者尝试过 iText,但是好像缺word模板的替换,但是项目中必须要有这个功能;
soa office, 还有国内的xxxx office 是要收费的,于是乎放弃使用了;
docx4j 有篇帖子写的很好,http://blog.csdn.net/zhyh1986/article/details/8766131,但是由于作者先尝试了poi2007,所以没有再尝试使用docx4j。
word2007模板字段和图片的替换
作者使用的是poi3.7版本,这里直接上代码吧。
WordUtil.java
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.openxml4j.opc.OPCPackage;
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;
/**
* 适用于word 2007
* poi 版本 3.7
*/
public class WordUtil {
/**
* 复制文件
* @param fromDocPath
* @param toDocPath
*/
public void saveTemplate(String fromDocPath,String toDocPath){
//String url = "/word/template/subproject.doc";
//String docPath = "c:/template/subproject.doc";
InputStream fis;
FileOutputStream fos;
int bytesum = 0;
int byteread = 0;
try {
fis = this.getClass().getResourceAsStream(fromDocPath);
fos = new FileOutputStream(toDocPath);
byte[] buffer = new byte[1444];
while ( (byteread = fis.read(buffer)) != -1) {
bytesum += byteread; //字节数 文件大小
fos.write(buffer, 0, byteread);
}
fis.close();
fos.close();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void saveTemplate(InputStream fis,String toDocPath){
FileOutputStream fos;
int bytesum = 0;
int byteread = 0;
try {
fos = new FileOutputStream(toDocPath);
byte[] buffer = new byte[1444];
while ( (byteread = fis.read(buffer)) != -1) {
bytesum += byteread; //字节数 文件大小
fos.write(buffer, 0, byteread);
}
fis.close();
fos.close();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 根据指定的参数值、模板,生成 word 文档
* @param param 需要替换的变量
* @param template 模板
*/
public static CustomXWPFDocument generateWord(Map<String, Object> param, String template) {
CustomXWPFDocument doc = null;
try {
OPCPackage pack = POIXMLDocument.openPackage(template);
doc = new CustomXWPFDocument(pack);
if (param != null && param.size() > 0) {
//处理段落
List<XWPFParagraph> paragraphList = doc.getParagraphs();
processParagraphs(paragraphList, param, doc);
//处理表格
Iterator<XWPFTable> it = doc.getTablesIterator();
while (it.hasNext()) {
XWPFTable table = it.ne