http://blog.csdn.net/fengyao1995/article/details/52443583 原文地址
项目需求要把页面上的分析结果导出为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>
- //导出分析结果
- 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();
- }
- @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;
- }
- }
- }