您的位置:首页 > 其它

使用poi操作模板文件重新生成新的word表单文件

2017-06-01 14:11 716 查看
问题:本人在项目中使用poi生成word表单文件,发现格式排版非常麻烦不说,还有个比较严重的问题是,wps跟office格式不兼容,用了2种方法都没有让这个两种打开的样式一致。不是office格式排版有问题就是wps格式排版有问题,研究了一天,最后决定用模板文件去生成新的文档比较容易,也不会有兼容性问题,并且也不用麻烦的去写很多样式做,而且可以简化代码变成工具类。解决了一个样式就要写一个生成类的问题,下面就来介绍一个下。

一、先来看一下模板文件

首先先创建一个格式符合要求的表单文档,所有需要动态值的地方用${}括起来自定义名称 例如${name}等等。



二、准备一个工具类。

package org.uz.dxt.common;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;

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 Xwp {
/**
* 此类为poi操作word模板的工具类
* @Author qixin at 2017-6-01
* */
/*String filePath = "/sta.docx";
InputStream is;
XWPFDocument doc;
Map<String, Object> params = new HashMap<String, Object>();

{
params.put("${name}", "xxx");
params.put("${sex}", "男");
params.put("${political}", "共青团员");
params.put("${place}", "sssss");
params.put("${classes}", "3102");
params.put("${id}", "213123123");
params.put("${qq}", "213123");
params.put("${tel}", "312313213");
params.put("${oldJob}", "sadasd");
params.put("${swap}", "是");
params.put("${first}", "asdasd");
params.put("${second}", "综合事务部");
params.put("${award}", "asda");
params.put("${achievement}", "完成科协网站的开发");
params.put("${advice}", "没有建议");
params.put("${attach}", "无");

try {
is = new FileInputStream(filePath);
doc = new XWPFDocument(is);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}*/

/**
* 用一个docx文档作为模板,然后替换其中的内容,再写入目标文档中。
*
* @throws Exception
*/
/*@Test
public void testTemplateWrite() throws Exception {
//替换段落里面的变量
this.replaceInPara(doc, params);
//替换表格里面的变量
this.replaceInTable(doc, params);
OutputStream os = new FileOutputStream("D:\\sta1.docx");
doc.write(os);
this.close(os);
this.close(is);
}*/

/*@Test
public void myTest1() throws Exception {
*//*Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
XWPFParagraph para;
while (iterator.hasNext()) {
para = iterator.next();
List<XWPFRun> runs = para.getRuns();
para.removeRun(0);
para.insertNewRun(0).setText("hello");
}

OutputStream os = new FileOutputStream("D:\\sta1.docx");
doc.write(os);
this.close(os);
this.close(is);*//*

System.out.println(this.matcher("报告日期:${reportDate}").find());

}*/

/*@Test
public void myReplaceInPara() {
//    Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
//    XWPFParagraph para;
//    while (iterator.hasNext()) {
//        para = iterator.next();
//        List<XWPFRun> runs = para.getRuns();
//
//
//    }

System.out.println('{'=='{');

}*/

/**
* 替换段落里面的变量
*
* @param doc    要替换的文档
* @param params 参数
*/
public void replaceInPara(XWPFDocument doc, Map<String, Object> params) {
Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
XWPFParagraph para;
while (iterator.hasNext()) {
para = iterator.next();
this.replaceInPara(para, params);
}
}

/**
* 替换段落里面的变量
*
*
10bfd
@param para   要替换的段落
* @param params 参数
*/
public void replaceInPara(XWPFParagraph para, Map<String, Object> params) {
List<XWPFRun> runs;
Matcher matcher;

runs = para.getRuns();

int start = -1;
int end = -1;
String str = "";
for (int i = 0; i < runs.size(); i++) {
XWPFRun run = runs.get(i);
String runText = run.toString();
System.out.println("------>>>>>>>>>" + runText);
if ('$' == runText.charAt(0)) {
start = i;
}
if ((start != -1)) {
str += runText;
}
if ('}' == runText.charAt(runText.length() - 1)) {
if (start != -1) {
end = i;
break;
}
}
}
System.out.println("start--->"+start);
System.out.println("end--->"+end);

System.out.println("str---->>>" + str);

for (int i = start; i <= end; i++) {
para.removeRun(i);
i--;
end--;
System.out.println("remove i="+i);
}

for (String key : params.keySet()) {
if (str.equals(key)) {
para.createRun().setText((String) params.get(key));
break;
}
}

}

/**
* 替换表格里面的变量
*
* @param doc    要替换的文档
* @param params 参数
*/
public 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) {
this.replaceInPara(para, params);
}
}
}
}
}
/**
* 关闭输入流
*
* @param is
*/
public void close(InputStream is) {
if (is != null) {
try {
is.close();
} catch ( Exception e) {
e.printStackTrace();
}
}
}

/**
* 关闭输出流
*
* @param os
*/
public void close(OutputStream os) {
if (os != null) {
try {
os.close();
} catch ( Exception e) {
e.printStackTrace();
}
}
}

}

package org.uz.dxt.common;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;

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 Xwp {
/**
* 此类为poi操作word模板的工具类
* @Author qixin at 2017-6-01
* */
/*String filePath = "/sta.docx";
InputStream is;
XWPFDocument doc;
Map params = new HashMap();

{
params.put("${name}", "xxx");
params.put("${sex}", "男");
params.put("${political}", "共青团员");
params.put("${place}", "sssss");
params.put("${classes}", "3102");
params.put("${id}", "213123123");
params.put("${qq}", "213123");
params.put("${tel}", "312313213");
params.put("${oldJob}", "sadasd");
params.put("${swap}", "是");
params.put("${first}", "asdasd");
params.put("${second}", "综合事务部");
params.put("${award}", "asda");
params.put("${achievement}", "完成科协网站的开发");
params.put("${advice}", "没有建议");
params.put("${attach}", "无");

try {
is = new FileInputStream(filePath);
doc = new XWPFDocument(is);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}*/

/**
* 用一个docx文档作为模板,然后替换其中的内容,再写入目标文档中。
*
* @throws Exception
*/
/*@Test
public void testTemplateWrite() throws Exception {
//替换段落里面的变量
this.replaceInPara(doc, params);
//替换表格里面的变量
this.replaceInTable(doc, params);
OutputStream os = new FileOutputStream("D:\\sta1.docx");
doc.write(os);
this.close(os);
this.close(is);
}*/

/*@Test
public void myTest1() throws Exception {
*//*Iterator iterator = doc.getParagraphsIterator();
XWPFParagraph para;
while (iterator.hasNext()) {
para = iterator.next();
List runs = para.getRuns();
para.removeRun(0);
para.insertNewRun(0).setText("hello");
}

OutputStream os = new FileOutputStream("D:\\sta1.docx");
doc.write(os);
this.close(os);
this.close(is);*//*

System.out.println(this.matcher("报告日期:${reportDate}").find());

}*/

/*@Test
public void myReplaceInPara() {
//    Iterator iterator = doc.getParagraphsIterator();
//    XWPFParagraph para;
//    while (iterator.hasNext()) {
//        para = iterator.next();
//        List runs = para.getRuns();
//
//
//    }

System.out.println('{'=='{');

}*/

/**
* 替换段落里面的变量
*
* @param doc    要替换的文档
* @param params 参数
*/
public void replaceInPara(XWPFDocument doc, Map params) {
Iterator iterator = doc.getParagraphsIterator();
XWPFParagraph para;
while (iterator.hasNext()) {
para = iterator.next();
this.replaceInPara(para, params);
}
}

/**
* 替换段落里面的变量
*
* @param para   要替换的段落
* @param params 参数
*/
public void replaceInPara(XWPFParagraph para, Map params) {
List runs;
Matcher matcher;

runs = para.getRuns();

int start = -1;
int end = -1;
String str = "";
for (int i = 0; i < runs.size(); i++) {
XWPFRun run = runs.get(i);
String runText = run.toString();
System.out.println("------>>>>>>>>>" + runText);
if ('$' == runText.charAt(0)) {
start = i;
}
if ((start != -1)) {
str += runText;
}
if ('}' == runText.charAt(runText.length() - 1)) {
if (start != -1) {
end = i;
break;
}
}
}
System.out.println("start--->"+start);
System.out.println("end--->"+end);

System.out.println("str---->>>" + str);

for (int i = start; i <= end; i++) {
para.removeRun(i);
i--;
end--;
System.out.println("remove i="+i);
}

for (String key : params.keySet()) {
if (str.equals(key)) {
para.createRun().setText((String) params.get(key));
break;
}
}

}

/**
* 替换表格里面的变量
*
* @param doc    要替换的文档
* @param params 参数
*/
public void replaceInTable(XWPFDocument doc, Map params) {
Iterator iterator = doc.getTablesIterator();
XWPFTable table;
List rows;
List cells;
List 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) {
this.replaceInPara(para, params);
}
}
}
}
}
/**
* 关闭输入流
*
* @param is
*/
public void close(InputStream is) {
if (is != null) {
try {
is.close();
} catch ( Exception e) {
e.printStackTrace();
}
}
}

/**
* 关闭输出流
*
* @param os
*/
public void close(OutputStream os) {
if (os != null) {
try {
os.close();
} catch ( Exception e) {
e.printStackTrace();
}
}
}

}


三、操作类

package org.uz.dxt.service.bankbase.impl;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.zip.Adler32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.uz.dxt.common.Xwp;
import org.uz.dxt.model.bankbase.PeopleVisit;
import org.uz.dxt.util.DateUtil;

/**
*
* @Description:Task下载生成流
*/
public class DownLoadTable {
private Logger log = LoggerFactory.getLogger(DownLoadTemplet.class);
// Word生成的格式
private final String FONT_FAMILY = "宋体";
private final int TITLE_FONT_SIZE = 20;
private final int BODY_FONT_SIZE = 12;
private final String TITLE_FONT_COLOR = "000000";
private final String BOFY_FONT_COLOR = "555555";
// 下载文件的地址
private final String HOST_URL = "http://wiscc6911.qnoddns.org.cn:8400/file/web/download/";

private PeopleVisit task;
private Map<String, byte[]> fileMap=new HashMap<String, byte[]>();

public DownLoadTable() {

}

public DownLoadTable(Map<String, Object> params,String templatePath,String wordFileName) {
CreateWord(params,templatePath,wordFileName);
}
/**
*
* @Description:生成word 并把word 流 和录音流放入 fileMap中
* @Date:2015-12-17
* @return
*/
private void CreateWord( Map<String, Object> params,String templatePath,String wordFileName) {

XWPFDocument doc = new XWPFDocument();
ByteArrayOutputStream bt = new ByteArrayOutputStream();
Xwp xwpfTUtil = new Xwp();
try {

/*String templatePath = "e:/word/model.docx";  */
InputStream is = new FileInputStream(templatePath);

doc = new XWPFDocument(is);
//替换段落里面的变量
xwpfTUtil.replaceInPara(doc, params);
//替换表格里面的变量
xwpfTUtil.replaceInTable(doc, params);

doc.write(bt);
xwpfTUtil.close(bt);

bt.flush();
bt.close();

//word文件名拼装
/*String wordFileName="外访报告信息填写模板";*/
wordFileName+="-"+DateUtil.formatDate(new Date())+".docx";

//word 放入fileMap中
fileMap.put(wordFileName, bt.toByteArray());

// bt.close();

} catch (Exception e) {
e.printStackTrace();
log.error("create word {}" + e.getMessage());
}
}

/**
*
* @Description:zip 打包
* @Date:2015-12-17
* @return
*/
public byte[] createZip(){
ByteArrayOutputStream zipByte = new ByteArrayOutputStream();
//输出流校验,采用Adler32 更快
CheckedOutputStream csum = new CheckedOutputStream(zipByte, new Adler32());
ZipOutputStream zos=new ZipOutputStream(csum);
try{
Iterator<String> fileNames=fileMap.keySet().iterator();
while(fileNames.hasNext()){
String fileName=fileNames.next();
byte[] fileByte=fileMap.get(fileName);
ZipEntry entry = new ZipEntry(fileName);
entry.setSize(fileByte.length);
zos.putNextEntry(entry);
zos.write(fileByte);
}
zos.closeEntry();
zos.close();
return zipByte.toByteArray();
}catch (Exception e) {
e.printStackTrace();
try {
zipByte.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
return null;
}

/**
*
* @Description:从文件服务器获取文件流
* @Date:2015-12-16
* @param fileDownUrl
* @param fileId
* @return
* @throws Exception
*/
private  InputStream getImage(String fileDownUrl) throws Exception{
log.debug(fileDownUrl);

URL url;
InputStream in=null;
url = new URL(fileDownUrl);
HttpURLConnection request=(HttpURLConnection) url.openConnection();
request.setRequestMethod("GET");
request.setConnectTimeout(5*1000);
request.setDoInput(true);

log.debug(""+request.getResponseCode());
if(request.getResponseCode()==200)
{
log.debug(""+request.getResponseCode());
in=request.getInputStream();
return in;
}
log.debug("return null");
return null;
}
/**
*
* @Description: input转byte[]
* @Date:2015-12-17
* @param in
* @return
* @throws IOException
*/
private byte[] inputStreamToByte(InputStream in) throws IOException{
ByteArrayOutputStream out=new ByteArrayOutputStream();
int len=0;
byte[] buffer=new byte[1024];
while((len=in.read(buffer))!=-1){

out.write(buffer, 0, len);

}

return out.toByteArray();

}

}


四 、controller类调用方法
/**
* 下载外访报告的模板
*
* @param
* @author qixin
* @return
*/
@RequestMapping("/out/downloadTemplet")
public ResponseEntity<byte[]> downloadTemplet(Model model,HttpServletRequest request,HttpSession session,String visitId){

String userId=null;
Object sessions = session.getAttribute("user");
if (sessions == null) {
return null;
}
if (User.class.equals(sessions.getClass())) {
User user = (User) sessions;
userId=Integer.toString(user.getId());
}

VisitApply visitApply=new VisitApply();
visitApply.setVisitId(visitId);
//获取外访申请信息
VisitApply info=outVisitServiceimpl.selectVisitApplyData(visitApply);
//获取案件信息
CaseHead t = new CaseHead();
t.setCaseid(info.getCaseid());
t.setCompanycode(info.getCompanyCode());
CaseBo caseBo=caseHeadService.getCaseHeadDetailByExample(t);
//获取案件联系方式信息
CaseContact caseContact=new CaseContact();
caseContact.setCaseid(info.getCaseid());
List<CaseContact> contacts=caseContactService.selectCaseConcatList(caseContact);

//生成文件名称
String fileName="外访报告填写模板"+DateUtil.formatDate(new Date())+".zip";
//生成下载文件word
/*DownLoadTemplet download=new DownLoadTemplet(info,caseBo,contacts);*/
//生成下载文件word表单
/*DownLoadTableTemplet download=new DownLoadTableTemplet(info,caseBo,contacts);*/
//生成下载文件word模板替换生成表单
Map<String, Object> params=dowloadWordService.dowloadModelWord(info, caseBo, contacts);
//模板地址
String templatePath = this.getClass().getClassLoader().getResource("/model.docx").getPath();

System.out.println(templatePath);
String wordFileName="外访报告信息填写模板";//生成文件名
DownLoadTable download=new DownLoadTable(params,templatePath,wordFileName);

byte[] taskFile=download.createZip();
HttpHeaders headers = new HttpHeaders();
//下载
if(taskFile!=null){
headers.setContentLength(taskFile.length);
}
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
setFileName(request, headers, fileName);
//下载文件
return new ResponseEntity<byte[]>(taskFile, headers, HttpStatus.OK);

}


五,params参数的sercive实现类

package org.uz.dxt.service.bankbase.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;
import org.uz.dxt.model.bankbase.CaseBo;
import org.uz.dxt.model.bankbase.VisitApply;
import org.uz.dxt.model.common.CaseContact;
import org.uz.dxt.service.bankbase.DowloadWordService;

@Service
public class DowloadWordServiceImpl implements DowloadWordService {

@Override
public Map<String, Object> dowloadModelWord(VisitApply info, CaseBo caseBo, List<CaseContact> contacts) {

Map<String, Object> params = new HashMap<String, Object>();
params.put("${caseid}",  info.getCaseid());
params.put("${applyName}",  info.getApplyName());
params.put("${applyTime}", info.getApplyTime());
params.put("${visitPurpose}", info.getVisitPurpose());
params.put("${addressType}", info.getAddressType());
params.put("${appointName}", info.getAppointName());
params.put("${bankName}", info.getBankName());
params.put("${name}", info.getName());
params.put("${doccode}", info.getDoccode());
params.put("${cardcode}", info.getCardcode());
params.put("${overmoney}", info.getOvermoney());
String deputecapital="";
if(caseBo.getDeputecapital() != null){
deputecapital=caseBo.getDeputecapital().toString();
}else{
deputecapital="无";
}

String moneybalance="";
if(caseBo.getMoneybalance() != null){
moneybalance=caseBo.getMoneybalance().toString();
}else{
moneybalance="无";
}
params.put("${deputecapital}", deputecapital);
params.put("${moneybalance}", moneybalance);
String contactInfo="";
if (contacts != null) {
for(int i=0;i<contacts.size();i++){
String type="";
String address="";
String name="";
if (contacts.get(i).getValid() != 0) {
if (contacts.get(i).getContacttype() == "0") {
type="电话";
}else if (contacts.get(i).getContacttype() == "1") {
type="邮件";
}else if (contacts.get(i).getContacttype() == "2") {
type="QQ";
}else if (contacts.get(i).getContacttype() == "3") {
type="微信";
}else if (contacts.get(i).getContacttype() == "4") {
type="地址";
}else {
type="无";
}

if (contacts.get(i).getCoofficeaddr() != null) {
address=contacts.get(i).getCoofficeaddr();
}else{
address="无";
}
if (contacts.get(i).getContactname() != null) {
name=contacts.get(i).getContactname();
}else{
name="不详";
}
contactInfo=contactInfo+"联系人:"+name+"  类型:"+type+"  关系:"+contacts.get(i).getRelation()+"  联系方式:"+contacts.get(i).getInfo()+"  单位地址:"+address;
}
}

}else{
contactInfo="无联系方式";
}

params.put("${visitAddress}", info.getVisitAddress());
params.put("${contactInfo}", contactInfo);
return params;
}

}

六、生成后的表单效果



七、如果觉得麻烦看的不太明白我建议一点一点尝试,这里放一个简单的测试main方法,当你使用这个明白以后再琢磨一下怎么适合自己的需求去写代码。

还是要用到xwp工具类,模板用本地路径即可,运行mian方法查看结果
package org.uz.dxt.service;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import org.apache.poi.xwpf.usermodel.XWPFDocument;

public class TestModel {

public static void main(String[] args) throws  Exception {
Map<String, Object> params = new HashMap<String, Object>();

params.put("${applyName}", "aaa");
params.put("${applyTime}", "bbb");
params.put("${visitPurpose}", "ccc");

Xwp xwpfTUtil = new Xwp();

XWPFDocument doc;
String templatePath = "e:/word/model.docx";  //模板路径
InputStream is = new FileInputStream(templatePath);

doc = new XWPFDocument(is);

//替换表格里面的变量
xwpfTUtil.replaceInTable(doc, params);
FileOutputStream fos = new FileOutputStream("e:/word/ddd.docx");//生成文档的路径

doc.write(fos);

xwpfTUtil.close(fos);

fos.flush();
fos.close();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: