项目需求要把页面上的分析结果导出为word文档,实现的办法是POI。查了一下网上很多方式都采用FreeMark,自己认为比较麻烦,所以还是采取了POI导出。之前的框架是SSH的,现在换成了Spring MVC,这次也把导出代码整理了一下。
页面效果是一个统计表,两个统计图,然后还有一些其他的统计数据,如下图所示:
首先需要一个word模板:
这个文档是自己制作的,里面每一个字母是占位符,将来数据是要放到这些字母的位置的。
下面是导出的代码:
1、在页面上添加一个隐藏的表单,表单中的隐含域是要往后台提交的参数。
<form method="post" name="dataform" id="dataform" action="" style="display:none;">
<input type="hidden" id="pieChart" name="pieChart" value=""/>
<input type="hidden" id="barChart" name="barChart" value=""/>
<input type="hidden" id="versionId" name="versionId" value=""/>
</form>
2、给表单隐含域赋值,并提交
//导出分析结果
function exportReport(){
var exportUrl = rootpath +"/atservice/analysis/wordOutPut";
//饼图统计图的base64码
$("#pieChart").val(pieChart.getDataURL());
//柱状图统计图的base64码
$("#barChart").val(barChart.getDataURL());
var versionId = $("#versions").val();
if(versionId != ""){
versionId = versionId.substring(0,versionId.indexOf(","));
}
$("#versionId").val(versionId);
$("#dataform").attr("action",exportUrl);
$("#dataform").submit();
}
3、Controller层获取数据,并传给相应的后台处理
@RequestMapping("/wordOutPut")
public void wordOutPut(@Param("versionId") String versionId,
@Param("pieChart") String pieChart,
@Param("barChart") String barChart, HttpServletRequest request,
HttpServletResponse response) throws IOException {
response.setCharacterEncoding(ATConstants.CHARACTER_ENCODING);
response.addHeader("Access-Control-Allow-Origin", "*");
File file = wordOutputService.wordOutPut(versionId, pieChart, barChart);
outPut(file, response);
}
public static void outPut(File file, HttpServletResponse response) {
try {
// 下载
OutputStream toClient = null;
InputStream is = null;
try {
String realFilePath = file.getAbsolutePath();//
// 创建文件目录
// String fileName = new String(("总体分析导出结果").getBytes("UTF-8"),
// "ISO8859_1") + ".docx";
String fileName = "总体分析结果" + ".docx";
// 设置response的Header
response.addHeader(
"Content-disposition",
"attachment;filename="
+ java.net.URLEncoder.encode(fileName, "UTF-8"));
toClient = response.getOutputStream();
response.setContentType("application/octet-stream");
// 以流的形式下载文件。
is = new FileInputStream(realFilePath);
byte b[] = new byte[1024];
int len = -1;
while ((len = is.read(b)) != -1)
toClient.write(b, 0, len);
toClient.flush();
} catch (IOException ex) {
throw ex;
} finally {
closeOut(toClient);
closeIn(is);
}
} catch (Exception e) {
log.error("下载附件出错,错误内容:", e);
}
}
public static void closeIn(InputStream in) {
try {
if (in != null) {
in.close();
}
} catch (Exception e) {
log.error("closeIn", e);
in = null;
}
}
public static void closeOut(OutputStream out) {
try {
if (out != null) {
out.close();
}
} catch (Exception e) {
log.error("closeIn", e);
out = null;
}
}
4、后台进行处理,处理的过程包括创建一个word文档,然后读取这个文档的位置,将数据以流的形式写入文档,最后保存下载。
//Service层方法:
import java.io.File;
import java.io.FileOutputStream;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import com.at21.landscaping.dao.LandAllAnalysisMapper;
import com.at21.landscaping.domain.WordConditionModel;
import com.at21.landscaping.util.ExportWordUtils;
import com.at21.landscaping.util.FileUtils;
import com.at21.landscaping.util.SQLUtil;
@Service
public class WordOutputService {
@Autowired
private JdbcTemplate jdbc;
@Autowired
private SQLUtil sqlutil;
private Properties pro;
private static final Logger log = Logger.getLogger(WordOutputService.class);
private WordConditionModel wordConditionModel = new WordConditionModel();
@Autowired
private LandAllAnalysisMapper landAnalysisMapper;
public File wordOutPut(String versionId, String pieChart, String barChart) {
// 获取所有参数
Map<String, String> map = new HashMap<String, String>();
// request.getParameterMap();
map.put("versionId", versionId);
map.put("pieChart", pieChart);
map.put("barChart", barChart);
wordConditionModel.setMap(map);
// 得到输出的EXCEL的默认file对象
File file = null;
try {
file = this.getWordFile();
} catch (Exception e) {
e.printStackTrace();
}
return file;
}
public File getWordFile() throws Exception {
Map<String, Object> param = this.getParam();
String templatename = this.getTemplateName();
return this.outPut(param, templatename);
}
public File outPut(Map<String, Object> param, String templatename)
throws Exception {
try {
String filePath = URLDecoder.decode(WordOutputService.class
.getResource("/").getPath(), "UTF-8");// +
if (filePath.indexOf("WEB-INF") != -1) {
filePath = filePath.substring(0, filePath.indexOf("WEB-INF")
+ ("WEB-INF").length());
}
filePath += File.separator + templatename;
XWPFDocument doc = ExportWordUtils.generateWord(param, filePath);
File docTemplaFile = new File(filePath);
File file = FileUtils.copyFile(docTemplaFile);
FileOutputStream fopts = new FileOutputStream(file);
doc.write(fopts);
fopts.close();
return file;
} catch (Exception e) {
log.error(e);
throw e;
}
}
public Map<String, Object> getParam() throws Exception {
String versionId = this.wordConditionModel.getMap().get("versionId")
.toString();
String versionName = "";
String zmj = "";
String lhmj = "";
String lhfgl = "";
List<Map<String, Object>> areaList = new ArrayList<Map<String, Object>>();
List<Map<String, Object>> tableList = new ArrayList<Map<String, Object>>();
if (versionId == "" && versionId.equals("")) {
versionId = landAnalysisMapper.queryNewestVersionGUID();
}
pro = sqlutil.getProperties();
String asql = pro.getProperty("ztfxArea");
asql = asql.replace("$versionId$", versionId);
areaList = jdbc.queryForList(asql);
String tsql = pro.getProperty("ztfxTable");
tsql = tsql.replace("$versionId$", versionId);
tableList = jdbc.queryForList(tsql);
if (areaList.size() != 0) {
versionName = areaList.get(0).get("periodname") + "";
zmj = areaList.get(0).get("allarea") + "";
lhmj = areaList.get(0).get("allgreenarea") + "";
lhfgl = areaList.get(0).get("grencoverrate") + "";
}
Map<String, Object> param = new HashMap<String, Object>();
param.put("a", versionName);// 数据集版本名称
param.put("b", zmj);// 建成区总面积
param.put("c", lhmj);// 建成区绿化覆盖面积
param.put("d", lhfgl);// 建成区绿化覆盖率
// 饼状图
String barChartbase64 = this.wordConditionModel.getMap()
.get("barChart");
if (StringUtils.isNotBlank(barChartbase64)) {
barChartbase64 = barChartbase64.substring(barChartbase64
.indexOf(",") + 1);
Map<String, Object> header3 = new HashMap<String, Object>();
header3.put("width", 400);
header3.put("height", 200);
header3.put("type", "jpg");
header3.put("content",
ExportWordUtils.base642ByteArray(barChartbase64));
param.put("e", header3);
}
// 柱状图
String pieChartbase64 = this.wordConditionModel.getMap()
.get("pieChart");
if (StringUtils.isNotBlank(pieChartbase64)) {
pieChartbase64 = pieChartbase64.substring(pieChartbase64
.indexOf(",") + 1);
Map<String, Object> header3 = new HashMap<String, Object>();
header3.put("width", 400);
header3.put("height", 200);
header3.put("type", "jpg");
header3.put("content",
ExportWordUtils.base642ByteArray(pieChartbase64));
param.put("f", header3);
}
param.put("g", tableList);// 统计表
return param;
}
public String getTemplateName() throws Exception {
String tamplateName = "/wordtemplate/ztfx.docx";
return tamplateName;
}
}
//ExportWordUtils工具类代码
package com.at21.landscaping.util;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.Document;
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;
import com.at21.base64.Base64;
import com.at21.landscaping.service.WordOutputService;
/**
* 适用于word 2007 poi 版本 3.7
*/
public class ExportWordUtils {
/**
* 根据指定的参数值、模板,生成 word 文档
*
* @param param
* 需要替换的变量
* @param template
* 模板
*/
public static XWPFDocument generateWord(Map<String, Object> param,
String template) {
XWPFDocument doc = null;
OPCPackage pack = null;
try {
pack = POIXMLDocument.openPackage(template);
doc = new XWPFDocument(pack);
if (param != null && param.size() > 0) {
// 处理段落 - 文字或照片
List<XWPFParagraph> paragraphList = doc.getParagraphs();
processParagraphs(paragraphList, param, doc, null, 0);
// 处理表格 - 文字或照片
List<XWPFTable> tablelist = doc.getTables();
for (int i = 0; i < tablelist.size(); i++) {
XWPFTable xwpfTable = tablelist.get(i);
List<XWPFTableRow> rows = xwpfTable.getRows();
for (int j = 0; j < rows.size(); j++) {
XWPFTableRow row = rows.get(j);
List<XWPFTableCell> cells = row.getTableCells();
for (int k = 0; k < cells.size(); k++) {
XWPFTableCell cell = cells.get(k);
List<XWPFParagraph> paragraphListTable = cell
.getParagraphs();
processParagraphs(paragraphListTable, param, doc,
xwpfTable, j);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return doc;
}
/**
* 处理段落
*
* @param paragraphList
* @throws Exception
*/
public static void processParagraphs(List<XWPFParagraph> paragraphList,
Map<String, Object> param, XWPFDocument doc, XWPFTable xwpfTable,
int rownum) throws Exception {
if (paragraphList != null && paragraphList.size() > 0) {
for (XWPFParagraph paragraph : paragraphList) {
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
String text = run.getText(0);
System.out.println(text);
if (text != null) {
boolean isSetText = false;
for (Entry<String, Object> entry : param.entrySet()) {
String key = entry.getKey();
if (text.indexOf(key) != -1) {
isSetText = true;
Object value = entry.getValue();
if (value instanceof String) {// 文本替换
text = text.replace(key, value.toString());
} else if (value instanceof Map) {// 图片替换
text = text.replace(key, "");
Map pic = (Map) value;
int width = Integer.parseInt(pic
.get("width") + "");
int height = Integer.parseInt(pic
.get("height") + "");
byte[] byteArray = (byte[]) pic
.get("content");
if (byteArray != null) {
ByteArrayInputStream byteInputStream = new ByteArrayInputStream(
byteArray);
try {
run.addPicture(byteInputStream,
Document.PICTURE_TYPE_JPEG,
"", Units.toEMU(width),
Units.toEMU(height));
} catch (Exception e) {
e.printStackTrace();
}
}
} else if (value instanceof List
&& xwpfTable != null) {// 图片替换
text = text.replace(key, "");
List<Map<String, Object>> _table = (List<Map<String, Object>>) value;
for (int i = 0; i < _table.size(); i++) {
// get row
if (i == 0) {
XWPFTableRow row = xwpfTable
.getRow(rownum);
Map<String, Object> rowdata = _table
.get(i);
int init = 0;
for (Iterator iterator = rowdata
.keySet().iterator(); iterator
.hasNext();) {
Object _key = iterator.next();
Object _value = rowdata
.get(_key);
XWPFTableCell cell = row
.getCell(init);
cell.setText(_value + "");
init++;
}
} else {
// create row
XWPFTableRow row = xwpfTable
.createRow();
Map<String, Object> rowdata = _table
.get(i);
int init = 0;
for (Iterator iterator = rowdata
.keySet().iterator(); iterator
.hasNext();) {
Object _key = iterator.next();
Object _value = rowdata
.get(_key);
XWPFTableCell cell = row
.getCell(init);
cell.setText(_value + "");
init++;
}
}
}
}
}
}
if (isSetText) {
run.setText(text, 0);
}
}
}
}
}
}
/**
* 将输入流中的数据写入字节数组
*
* @param in
* @return
*/
public static byte[] inputStream2ByteArray(InputStream in, boolean isClose) {
byte[] byteArray = null;
try {
int total = in.available();
byteArray = new byte[total];
in.read(byteArray);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (isClose) {
try {
in.close();
} catch (Exception e2) {
}
}
}
return byteArray;
}
/**
* 将输入流中的数据写入字节数组
*
* @param in
* @return
*/
public static byte[] base642ByteArray(String base64str) {
byte[] byteArray = null;
try {
byteArray = Base64.decode(base64str);
} catch (Exception e) {
e.printStackTrace();
}
return byteArray;
}
/**
* 将输入流中的数据写入字节数组
*
* @param in
* @return
*/
public static byte[] localImage2ByteArray(String filename) {
byte[] byteArray = null;
try {
String filePath = URLDecoder.decode(WordOutputService.class
.getResource("/").getPath(), "UTF-8");// +
// excelTemplateUrl;
if (filePath.indexOf("WEB-INF") != -1) {
filePath = filePath.substring(0, filePath.indexOf("WEB-INF")
+ ("WEB-INF").length());
}
filename = filePath + File.separator + "wordtemplate"
+ File.separator + filename;
byteArray = FileUtils.readFileToByteArray(new File(filename));
} catch (Exception e) {
e.printStackTrace();
}
return byteArray;
}
public static byte[] remoteImage2ByteArray(String imageUrl) {
byte[] byteArray = null;
try {
HttpClient httpClient = new DefaultHttpClient();
// 建立HttpGet
HttpGet httpGet = new HttpGet(imageUrl);
// 添加参数
httpGet.getParams().setParameter("http.conn-manager.timeout",
Long.valueOf(1000L));
httpGet.getParams().setParameter("http.connection.timeout",
Integer.valueOf(2000));
httpGet.getParams().setParameter("http.socket.timeout",
Integer.valueOf(10000));
// 发送请求返回httpResponse
HttpResponse httpResponse = httpClient.execute(httpGet);
// 请求返回的状态码,如果为200则成功,否在失败
int statusCode = httpResponse.getStatusLine().getStatusCode();
if (statusCode == 200) {
byteArray = EntityUtils.toByteArray(httpResponse.getEntity());
}
} catch (Exception e) {
e.printStackTrace();
}
return byteArray;
}
}
//FileUtils工具类代码,这是对FileUtils类的封装
package com.at21.landscaping.util;
import java.io.File;
import java.util.Calendar;
public class FileUtils {
public static File copyFile(File file)throws Exception {
try{
File dest = new File(Constants.DEFAULTTMPFILEURL+Calendar.getInstance().getTime().getTime()+".xls");
org.apache.commons.io.FileUtils.copyFile(file, dest);
return dest;
}catch(Exception e){
throw e;
}
}
}
以上就是导出word文档的全部内容,导出的word文档的截图忘了截了,下次再给补上。如果有什么瑕疵,还请过路的各位大牛指点一二。