java 根据模板,导出word并提供下载

最近项目需要,需要将文本信息下载为doc文件(带图片),小白通过在网上查找资料实现了这个功能

先引入freemarker的jar包

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.13</version>
</dependency>

制作模板文件:

新建一个word文件:

 英文部分是后面需要替换的内容,插入图片,后面也需要替换

将文件另存为xml,编辑器打开xml文件,将上述英文部分用${....}替换,${....}中的内容是后台传递过来的值(你需要显示的内容),doc中的图片在xml中被解析成一长串的base64编码,需要用${image}代替base64编码。最后将xml文化后缀改为ftl,并将ftl文件放到你项目中

下面是后台代码:

建立工具类

package com.jhzj.common.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import com.jhzj.entity.bussiness.attendance.LeaveDto;

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

public class WordUtil {
	
	private Configuration configuration = null;
	
	public WordUtil() {
		configuration = new Configuration();
		configuration.setDefaultEncoding("UTF-8");
	}
	
	/**
	 *   将文本信息转为word输出
	 * @param dto
	 * @throws Exception 
	 */
	public File createDoc(LeaveDto dto) {
		Map<String,Object> dataMap = new HashMap<>();
		getData(dataMap,dto); //创建数据
		configuration.setClassForTemplateLoading(this.getClass(), ""); //模板文件所在路径
		Template t = null;
		
		String fileName = dto.getUserName()+"-请假.doc";
		File file = new File(fileName);
		try {
			t = configuration.getTemplate("leaveoff.ftl"); //获取模板文件
			t.setEncoding("utf-8");
			
			Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName),"utf-8"));
			t.process(dataMap, out);  //将填充数据填入模板文件并输出到目标文件
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TemplateException e) {
			e.printStackTrace();
		}
		
		return file;
	}
	
	/**
	 * 导出word 并提供下载
	 * @param response
	 */
	public void download(HttpServletResponse response,LeaveDto dto) {
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			File file = createDoc(dto);
			String fileName = dto.getUserName()+"-请假.doc";
			
			response.setContentType("application/msword;charset=utf-8");
			response.addHeader("Content-Disposition", "attachment; filename=\""
		            + new String(fileName.getBytes(),"iso-8859-1") + "\"");
			
			bis = new BufferedInputStream(new FileInputStream(file));
	        bos = new BufferedOutputStream(response.getOutputStream());
	       
	        byte[] buff = new byte[10240];
	        int bytesRead;
	        while(-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
	        	bos.write(buff, 0, bytesRead);
	        }
	        
	        bis.close();
	        bos.close();
			
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}
	
	
	//获得数据
	private void getData(Map<String,Object> dataMap, LeaveDto dto) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		dataMap.put("userName", dto.getUserName());
		dataMap.put("type", dto.getType());
		dataMap.put("startTime", sdf.format(dto.getStartTime()));
		dataMap.put("endTime", sdf.format(dto.getEndTime()));
		dataMap.put("reason", dto.getReason());
		System.out.println("=================="+dto.getPicture());
		String base64 = getBase64(dto.getPicture());
		dataMap.put("image", base64);
	}
	
	//获得图片的base64编码
	private String getBase64(String imgUrl) {
		ByteArrayOutputStream data = new ByteArrayOutputStream();
		URL url = null;
		InputStream in = null;
		HttpURLConnection httpUrl = null;
		byte[] by = new byte[1024];
		
		try {
			url = new URL(imgUrl);
			httpUrl = (HttpURLConnection)url.openConnection();
			httpUrl.connect();
			in = httpUrl.getInputStream();
			int len = -1;
			while((len = in.read(by)) != -1) {
				data.write(by, 0, len);
			}
			
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		BASE64Encoder encoder = new BASE64Encoder();
		return encoder.encode(data.toByteArray());
	}
	
}

Controller代码:

/**
	 * 下载信息
	 * @param id 请假id
	 * @return
	 */
	@RequestMapping(value = "/download")
	@ResponseBody
	public void downloadInfo(HttpServletResponse response,Integer id) {
		//if (doSecurityIntercept(Const.RESOURCES_TYPE_BUTTON){
			try {
				WordUtil wd = new WordUtil();
				LeaveDto dto = service.checkInfo(id);
				wd.download(response, dto);
				
			} catch (BussinessException e) {
				e.printStackTrace();
			}catch (Exception e) {
				logger.error(e.toString(), e);
				e.printStackTrace();
			} 
		//}
	}

备注:如果模板是表格的话,表头的第一行需要保留。

在列表前加入<#list list as l>(在它的头上加一个<#list 你的集合名称 as xxxx>),并在结尾加上</#list>,修改list内容,在要输出的名字前面加上l.。如xuehao,修改为l.xuehao。这样有点像EL表达式的使用。

 表格循环:

private void getData(Map<String, Object> dataMap) {  
	dataMap.put("title", "标题");  
	dataMap.put("nian", "2016");  
	dataMap.put("yue", "3");  
	dataMap.put("ri", "6");   
	dataMap.put("shenheren", "lc");  
        
    List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();  
    for (int i = 0; i < 10; i++) {  
    	Map<String,Object> map = new HashMap<String,Object>();  
        map.put("xuehao", i);  
        map.put("neirong", "内容"+i);  
        list.add(map);  
    }  
          
    dataMap.put("list", list);  
}  

 以上代码都是本人亲测可用!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值