freemarker根据模板生成word,并插入图片

1.将你的word模板根据下图插入需要填充的占位符,格式为${},大括号内放入传对应的值

2.审核者后面放的是一张电子签名的图片,这个位置将是我们要插入图片的位置

3.然后将你的word文件保存另存为xml文件

4.xml中可能看到的是这样$****{****}****隔开的,将中间的****删除掉,得到完整的${},如图

5.搜索<pkg:binaryData>,就可以看见一大串的字符串,这个是图片的base64码,如下图

6.可能会有多个大长字符串(注意:一个<pkg:binaryData></pkg:binaryData之间的长字符串代表一张图片),我的需求是要插入一张图片,将对应的长字符串删除用${image}代替,然后将xml文件改为ftl模板文件

搜索<w:pict>和<pkg:part>,他俩对应的是一张图片(多张图片就为多对),判断image不为空的时候才插入

8.我的需求是页面点击一个按钮,然后根据word模板生成报告

                                                                                         js代码

//生成报告按钮
tbarOpts.push({
	text: '<i class="fa fa-file-word-o"></i>' + " 生成报告",
	className: 'btn btn-sm btn-danger',
	action:function(){
		generateReport();
	}
})
//生成报告的方法
function generateReport(){
	var rows = $("#reportItem .selected");
	if(!rows.length){
		top.layer.msg(XXX.common.pleaseChoose);
		return false;
	}else if(rows.length > 1){
		top.layer.msg(XXX.common.pleaseChooseOne);
		return false;
	}
	var id = $(".selected").find("input").val();
	
	top.layer.confirm("请确认修改保存后在生成报告",
		{
		icon : 3,
		title : biolims.common.prompt,
		btn:biolims.common.selected
		},
		function(index) {
			top.layer.close(index);                
			window.open( ctx + "/reports/generateWorkReport.action?id=" + id);//后台的方法
			top.layer.msg(XXX.report.generateReportSuccess);
		});	
}

                                                                                            java代码

将之前设置的占位符${}大括号里面的与map中的key保持一致

        @Action(value = "generateWorkReport")
	public void generateWorkReport() throws Exception {
		HttpServletRequest request = ServletActionContext.getRequest();
		HttpServletResponse response = ServletActionContext.getResponse();
		Map<String, Object> map = null;
		String id = getRequest().getParameter("id");
		User user = (User) this
				.getObjFromSession(SystemConstants.USER_SESSION_KEY);
		map = reportService.generateWorkReport(id, user);
		User u = (User) map.get("auditUser");
		if(u!=null) {
			List<FileInfo> fileList = fileInfoService.findFileInfoList(u.getId(),"user");
			if(fileList.size()>0) {
				for (int i = 0; i<fileList.size() ; i++) {                 
					FileInfo fileInfo = fileList.get(0);//审核人身上的电子签名文件
					String fp = fileInfo.getFilePath();                    
					String image = getImageBase(fp);//将电子签名文件转为base64码
					map.put("image", image);
				}
			}else {
				map.put("image", "");
			}
		}else {
			map.put("image", "");
		}
		WordUtils.exportMillCertificateWord(request,response,map);
	}

    //获得图片的base64码
    @SuppressWarnings("deprecation")
    public String getImageBase(String src) {
        if(src==null||src==""){
            return "";
        }
        File file = new File(src);
        if(!file.exists()) {
            return "";
        }
        InputStream in = null;
        byte[] data = null;  
        try {
            in = new FileInputStream(file);
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }
        try {  
            data = new byte[in.available()];  
            in.read(data);  
            in.close();  
        } catch (IOException e) {  
          e.printStackTrace();  
        } 
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);
    }

生成word的工具类(注意templateFolder为模板存放的路径,将ftl模板放到该路径对应的文件夹中)

@SuppressWarnings("deprecation")
public class WordUtils {
	
    private static Configuration configuration = null;
    //这里注意的是利用WordUtils的类加载器动态获得模板文件的位置
    //相当tomcat下webapps中的template文件夹,如果不知道打开本地tomcat下项目看下就知道了
    private static final String templateFolder = WordUtils.class.getClassLoader().getResource("../../").getPath() + "template/";
    
    static {
        configuration = new Configuration();
        configuration.setDefaultEncoding("utf-8");
        try {
            configuration.setDirectoryForTemplateLoading(new File(templateFolder));
        } catch (IOException e) {
            e.printStackTrace();
        }
   }
 
    private WordUtils() {
    	
        throw new AssertionError();
    }
 
    public static void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map map) throws IOException {
    	String fn = (String) map.get("fileName");
    	String[] split = fn.split(".doc");
    	//根据doc模板的名称,传入对应名称的ftl模板
    	String ftlName = split[0];
        Template freemarkerTemplate = configuration.getTemplate(ftlName + ".ftl");
        File file = null;
        InputStream fin = null;
        ServletOutputStream out = null;
        try {
            // 调用工具类的createDoc方法生成Word文档
            file = createDoc(map,freemarkerTemplate);
            fin = new FileInputStream(file);
 
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/msword");
            // 设置浏览器以下载的方式处理该文件名
            String fileName = "检测报告单" + ".doc";
            response.setHeader("Content-Disposition", "attachment;filename="
                    .concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));
            out = response.getOutputStream();
            byte[] buffer = new byte[512];  // 缓冲区
            int bytesToRead = -1;
            // 通过循环将读入的Word文件的内容输出到浏览器中
            while((bytesToRead = fin.read(buffer)) != -1) {
                out.write(buffer, 0, bytesToRead);
            }
        } finally {
        	// 生成word后清除临时文件
            if(fin != null) fin.close();
            if(out != null) out.close();
            if(file != null) file.delete(); 
        }
    }
 
    private static File createDoc(Map<?, ?> dataMap, Template template) {
    	//具体的文件
    	String filePath = (String) dataMap.get("filePath");
//        String name =  "d:\\test.doc";
        File f = new File(filePath);
        Template t = template;
        try {
            // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
            Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
            t.process(dataMap, w);
            w.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
        return f;
    }
}

 

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值