再怎么忙,都要学会忙里偷闲,把学到的运用到的新技术,及时记录下来,有备无患!!!
最近公司开始新项目,老大分给自己的任务其中就有一个“Word报表导出”功能!
以前自己都是导出Excel表,从没实现过Word格式的,所以上网找了很多资料,总算让自己理解了它大概的实现原理。。。
既然有了思路,那就开始着手准备开发的必要工作,然后开始动工!!!
首先,你要导出Word格式的表格,就需要事先新建一个空白的Word文档;
然后,对它进行“你想要在项目中导出Word报表的样式”进行排版;排版搞定之后,就另保存为“word.xml”文件(名字随便取),记得,这一步很重要,别搞错了!
最后,把模板文件 word.xml 放在你项目的WebRoot/template目录下(有些人或公司偏好把webRoot改为webapp--比如我就是这样,但都是一个意思),再然后,在项目中把word.xml文件改为word.ftl , 接着对它进行el表达式的填参操作。如下图所示:
上面这些工作搞定之后,接下来就是开发工作了:
首先,在前端页面传参到controller;
然后,controller层拿到传参之后,进行一系列的业务逻辑操作,之后取到自己想要的值(这些值是你要输出到Word.ftl模板文件中),实现原理如下:
1.新建Configuration,是用于读取ftl文件;
2.指定word.ftl模板文件所在的目录路径,为了读取文件(注意:并不是word.ftl文件的路径!!!!);
3.设置Word文件生成路径(获取配置文件路径--服务器路径);
4.设置文件输入输出流,输出文档路径及名称,并以utf-8的编码格式读取word.ftl文件,传到Word.ftl文件;
5.把本地文件发送给客户端
6.关闭输入输出流,所有流程就结束啦~
controller代码如下所示:
public void exportReportFile(HttpServletRequest request,HttpServletResponse response)throws Exception{
Number TEST_ID = Integer.parseInt(request.getParameter("TEST_ID"));
String DEV_NAME = request.getParameter("DEV_NAME").trim();
DataRecord pdTestTask = new DataRecord();
List<DataRecord> cableList = new ArrayList<DataRecord>();
List<DataRecord> resultList = new ArrayList<DataRecord>();
pdTestTask = service.getPDTaskList(TEST_ID);
cableList = service.getCableList(DEV_NAME);
resultList = service.getAnalysisResultList(TEST_ID, DEV_NAME);
Map<String, Object> domain = new HashMap<String, Object>();
/*DataRecord domain = new DataRecord();*/
DateFormat df = new DateFormat();
String dateTime = df.DateToString_Format(pdTestTask.getDate("BEGIN_TIME"), "yyyy-MM-dd");
domain.put("dateTime", dateTime);
domain.put("weather", pdTestTask.getString("WEATHER"));
domain.put("temperature", pdTestTask.getLong("TEMPERATURE"));
domain.put("humidity", pdTestTask.getLong("HUMIDITY"));
domain.put("cableName", DEV_NAME);
String startWorkTime = df.DateToString_Format(pdTestTask.getDate("BEGIN_TIME"), "yyyy-MM-dd");
domain.put("commissionTime", startWorkTime);
domain.put("inspectorName", pdTestTask.getString("TESTERS"));
List<DataRecord> cableList2 = new ArrayList<DataRecord>();
for(DataRecord dr : cableList){
domain.put("cableName", dr.getString("DEV_NAME"));
domain.put("voltageLevel", dr.getString("POWER_LEVEL"));
DataRecord systemDEV = service.getCableStandards(dr.getLong("DEV_ID"));
if(dr.getString("PHASE").equals("A")){
dr.put("STANDARDS", systemDEV.getString("STANDARDS"));
}else if(dr.getString("PHASE").equals("B")){
dr.put("STANDARDS", systemDEV.getString("STANDARDS"));
}
else{
dr.put("STANDARDS", systemDEV.getString("STANDARDS"));
}
cableList2.add(dr);
}
domain.put("cableList", cableList2);
domain.put("resultList", resultList);
//Configuration 用于读取ftl文件
Configuration configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
// 以下是指定ftl文件所在目录路径的方式,而不是ftl文件的路径
//模板文件word.xml是放在WebRoot/template目录下的
configuration.setServletContextForTemplateLoading(request.getSession().getServletContext(), "/template");
//设置Word文件生成路径(获取配置文件路径--服务器路径)
File savePathTemp=new File(SbpConfig.getProperty("sbp.doc.savepath")+"/templateFile");
String fileName="高压电缆局放检测报告.doc";
String filePath=savePathTemp+"/"+fileName;
//输出文档路径及名称
File outFile = new File(filePath);
//以utf-8的编码读取ftl文件
Template template = configuration.getTemplate("pdTestReport.ftl", "utf-8");
Writer outWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"));
template.process(domain, outWriter);
OutputStream out;//输出响应正文的输出流
InputStream in;//读取本地文件的输入流
//获得本地输入流
File savePath=new File(SbpConfig.getProperty("sbp.doc.savepath")+"/"+"templateFile");
File file = new File(savePath+"/"+fileName);
in = new FileInputStream(file);
//针对不同浏览器,下载需不同转码
String userAgent = request.getHeader("User-Agent");
//针对IE或者以IE为内核的浏览器:
if (userAgent.contains("MSIE")||userAgent.contains("Trident")) {
fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
} else {
//非IE浏览器的处理:
fileName = new String(fileName.getBytes("UTF-8"),"ISO-8859-1");
}
response.setHeader("Content-disposition", String.format("attachment; filename="%s"", fileName));
response.setCharacterEncoding("UTF-8");
//设置响应正文的MIME类型
response.setContentType("Content-Disposition;charset=UTF-8");
//把本地文件发送给客户端
out = response.getOutputStream();
int byteRead = 0;
byte[] buffer = new byte[512];
while((byteRead = in.read(buffer)) != -1) {
out.write(buffer, 0, byteRead);
}
in.close();
out.close();
}