用word模板导出word文档

    项目需求要把页面上的分析结果导出为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文档的截图忘了截了,下次再给补上。如果有什么瑕疵,还请过路的各位大牛指点一二。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 17
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值