用word模板导出word文档

来源:互联网 发布:中国年鉴数据库 编辑:程序博客网 时间:2024/04/29 01:51

    项目需求要把页面上的分析结果导出为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的Headerresponse.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;@Servicepublic class WordOutputService {@Autowiredprivate JdbcTemplate jdbc;@Autowiredprivate SQLUtil sqlutil;private Properties pro;private static final Logger log = Logger.getLogger(WordOutputService.class);private WordConditionModel wordConditionModel = new WordConditionModel();@Autowiredprivate 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 rowif (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 rowXWPFTableRow 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();// 建立HttpGetHttpGet 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));// 发送请求返回httpResponseHttpResponse 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文档的截图忘了截了,下次再给补上。如果有什么瑕疵,还请过路的各位大牛指点一二。
1 0
原创粉丝点击