FreeMaker+Xml导出word(含图片)

29 篇文章 5 订阅

最近在做一个简报导出的功能,要求导出word格式,上网找了很多资料,一开始选择了poi后来发现poi只能导出简单的word数据,后来偶然发现了通过FreeMaker模板生成word,说实话,还挺好用的!下面是我的一个demo!


第一步:制定word模板



第二步:另存为xml格式




第三步:将修改后的xml模版保存为ftl格式

  1、修改生成的xml文件

  2、<#list newsList as listKey>为FreeMaker的用法,迭代newsList中的数据





图片:



如果你需要在word中添加图片,那你就在第一步制作模板时,加入一张图片占位,然后打开xml文档,可以看到如下的一片base64编码后的代码:

 <w:binData w:name="wordml://03000001.png" xml:space="preserve">iVBORw0…(很省略很省略)…CC</w:binData>

只要将 base64 的代码替换成例如: ${image} ,如下:

//后台代码如下

//word生成工具类,可直接本地生成

package com.tgb.web;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import sun.misc.BASE64Encoder;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

public class t2 {

	private Configuration configuration = null;

	public t2() {
		configuration = new Configuration();
		configuration.setDefaultEncoding("UTF-8");
	}

	/**
	 * 以下载的方式生成word,自定义路径
	 * @param dataMap
	 * @param out
	 */
	public void createDoc(Map<String, Object> dataMap,Writer out) {

		// 设置模本装置方法和路径,FreeMarker支持多种模板装载方法。可以重servlet,classpath,数据库装载,
		// ftl文件存放路径
		configuration.setClassForTemplateLoading(this.getClass(), "/config/spring");

		Template t = null;
		try {
			// test.ftl为要装载的模板
			t = configuration.getTemplate("yuqing_brief_template2.ftl");
			t.setEncoding("utf-8");
		} catch (IOException e) {
			e.printStackTrace();
		}

		try {
			t.process(dataMap, out);
		} catch (TemplateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
	
	/**
	 * 传入数据 可直接本地生成word
	 * @param dataMap
	 */
	public void createDoc(Map<String, Object> dataMap) {

		// 设置模本装置方法和路径,FreeMarker支持多种模板装载方法。可以重servlet,classpath,数据库装载,
		// ftl文件存放路径
		configuration.setClassForTemplateLoading(this.getClass(), "/config/spring");

		Template t = null;
		try {
			// test.ftl为要装载的模板
			t = configuration.getTemplate("t2_img.ftl");
			t.setEncoding("utf-8");
		} catch (IOException e) {
			e.printStackTrace();
		}

		// 输出文档路径及名称
		File outFile = new File("H:/'" + Math.random()*10000 + "'t2_img.doc");
		Writer out = null;
		try {
			out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"));
		} catch (Exception e1) {
			e1.printStackTrace();
		}

		try {
			t.process(dataMap, out);
			out.close();
		} catch (TemplateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	/**
	 * 
	 * 注意dataMap里存放的数据Key值要与模板中的参数相对应
	 * 
	 * @param dataMap
	 */
	private Map<String, Object> getData() {
		Map<String, Object> dataMap = new HashMap<String, Object>();
		Map<String, Object> map1 = new HashMap<String, Object>();
		Map<String, Object> map2 = new HashMap<String, Object>();

		map1.put("title", "国泰君安*公司研究*广发证券:定增完成,如虎添翼*000776*投资银行业与经纪业行业*梁静");
		map1.put("content","报告类型=公司事件点评公司简称=广发证券公司代码=000776报告日期=Thu Aug 25 09:05:29 CST 2011研究员 =梁静报告标题=定增完成");
		map1.put("site", "上海证卷报");
		String img1 = getImageStr("H:/Tulips.jpg");
		map1.put("image", img1);
		map1.put("i", 1);//标识图片

		map2.put("title", "[申万销售夏敬慧] 基金仓位周报----开基仓位下降1.51%");
		map2.put("content","理财产品部分析师: 杨鹏(18930809297) 开基仓位有所下降:本周,开放式基金平均仓位继续下降。");
		map2.put("site", "上海证卷报");
		String img2 = getImageStr("H:/Penguins.jpg");
		map2.put("image", img2);
		map2.put("i", 2);//标识图片

		List<Map<String, Object>> newsList = new ArrayList<Map<String, Object>>();
		newsList.add(map1);
		newsList.add(map2);
		dataMap.put("newsList", newsList);
		return dataMap;
	}

	public String getImageStr(String imgFile) {
		InputStream in = null;
		byte[] data = null;
		try {
			in = new FileInputStream(imgFile);
			data = new byte[in.available()];
			in.read(data);
			in.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		BASE64Encoder encoder = new BASE64Encoder();
		return encoder.encode(data);
	}

	public static void main(String[] args) {
		t2 word = new t2();
		Map<String,Object> map = word.getData();
		word.createDoc(map);
	}

}


 
//控制层代码(本人用的是springmvc)
<span style="white-space:pre">	</span>@RequestMapping(value="/exportword")
	@ResponseBody
	public String exportWord(HttpServletRequest request,HttpServletResponse response) throws IOException{
		response.setContentType("application/octet-stream; charset=UTF-8");  
		response.setHeader("content-disposition", "attachment;filename=" + new SimpleDateFormat("yyyyMMddHH:mm:ss").format(new Date()) + ".doc");
		Writer out = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(),"utf-8"));//重点:一定要注意编码格式,漏写编码格式将导致word无法打开(xml非法字符)		
		t2 word = new t2();
		Map<String, Object> map = userService.getData();
		word.createDoc(map,out);
		out.flush();
		out.close();
		return null;
	}

OK!搞定,希望对有需要的人有用!
 

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值