velocity往word/excel模版填充数据并导出

     国企或政府单位的项目,经常有这样的需求,把用户填写的数据填充到word或excel模版,然后导出的需求。网上也有解决方案。现在记录下自己的学习过程。采取的方案也是把word或excel转为2003的xml,然后在xml中写velocity的语法,使用velocity引擎解析xml,然后导出(web项目)。这方案唯一不好的地方就是,如果模版稍微改动,那就得重新做一次了。

1.代码

maven加上velocity架包

	    org.apache.velocity
	    velocity
	    1.7
	
 写个VelocityUtil.java类,需要往word或excel填充数据,并导出,调用createDoc方法就行了。模版放在WEB-INF/vm文件夹下.
package com.qhgrain.app.gway.util;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.Properties;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
/**
 * 用于解析vm模版(world文档保存为xml格式,然后把里面的值改为velocity变量)
 * @author Jfei
 *注意:解析excel的xml模版时,必须把
 *删掉才行,否则velocity处理模版后,导出的xls会出现内容空白问题
 */
public class VelocityUtil {

	 private static final Object LOCK = new Object();

	 /**
	  * word文件
	  */
	 public static final int WORD_FILE = 1;
	 /**
	  * excel文件
	  */
	 public static final int EXCEL_FILE = 2;
	 
	 private static VelocityEngine ve;
	 
	 private static VelocityUtil v ;
	 
     private VelocityUtil(String templateFolder) {
    	 Properties properties = new Properties();
         properties.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, templateFolder);
         ve = new VelocityEngine();
         ve.init(properties);
         ve.init();
     }

    private static void check(HttpServletRequest request) {
        if (v == null) {
            synchronized (LOCK) {
                v = new VelocityUtil(request.getServletContext().getRealPath("/")+"WEB-INF"+File.separator+"vm");
            }
        }
       
    }


    /**
     * 创建 word 文档
     * 必须先设置response导出配置,然后解析模版,否则会出问题
     * @throws IOException 
     */
    public static void createDoc(String templateName, VelocityContext vc,HttpServletRequest request, HttpServletResponse response,String docFileName,int fileType) throws IOException {
  //  	response.resetBuffer();
    	
    	//设置导出
        
        response.addHeader("Cache-Control","no-cache");
        response.setCharacterEncoding("UTF-8");
        if( WORD_FILE == fileType){
        	response.setContentType("application/vnd.ms-word;charset=UTF-8");
        }else if(EXCEL_FILE == fileType){
        	response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        }else{
        	response.setContentType("application/octet-stream");
        }
        
       
        String ua = request.getHeader("user-agent");
        ua = ua == null ? null : ua.toLowerCase();
        if(ua != null && (ua.indexOf("firefox") > 0 || ua.indexOf("safari")>0)){
        	try {
        		docFileName = new String(docFileName.getBytes(),"ISO8859-1");
        		 response.addHeader("Content-Disposition","attachment;filename=" + docFileName);
			} catch (Exception e) {
			}
        }else{
        	try {
				docFileName = URLEncoder.encode(docFileName, "utf-8");
		        response.addHeader("Content-Disposition","attachment;filename=" + docFileName);
			} catch (Exception e) {
			}
        }
        
        
    	//解析模版
        check(request);
    	Template template = ve.getTemplate(templateName, "UTF-8");
        PrintWriter write = response.getWriter();
        template.merge(vc, write);
        
        
        if(write != null){
        	write.flush();
        	write.close();
        }
    }
    
  
}
  action或controller中这样调用即可
@RequestMapping("/hurrySupplyFormExport")
	public void hurrySupplyCompanyExport(HurrySupplyApplyInfo applyInfo , HttpServletRequest request,HttpServletResponse response) throws IOException{
		VelocityContext vc = new VelocityContext();
		vc.put("info", applyInfo);
		VelocityUtil.createDoc("hurry_supply_apply.vm", vc, request, response, "XXXXX企业资格申请表.xls",VelocityUtil.EXCEL_FILE);
	
	}

2.word的处理

  比如有下面这样的一个word模版
velocity往word/excel模版填充数据并导出_第1张图片

      将它另存为xml格式,然后还是word文档打开它,往里面填写数据,方便手动处理xml文件手写velocity。
   velocity往word/excel模版填充数据并导出_第2张图片


     然后保存,然后记事本打开,复制放到网上xml格式化下(好看点),解决手写velocity。想下面这样

velocity往word/excel模版填充数据并导出_第3张图片

velocity往word/excel模版填充数据并导出_第4张图片

  这样就OK了。

3.excel的处理

   excel的处理也和word一样,先转为xml。接下来可以直接在excel中手动写velocity再保存,excel不会把你写的velocity截断。有个特别需要注意的地方,就是转为xml后,记事本打开xml,手动把把这个删掉,否则velocity解析的时候会把后面那部分给直接删了,导致导出来的xls文件,打开时是一片空白(这个坑,坑了我)

velocity往word/excel模版填充数据并导出_第5张图片


但是如果是打勾勾选的,那需要先在页面把打勾和没打勾的2个符号先写上,然后在xml中手动处理。

velocity往word/excel模版填充数据并导出_第6张图片





你可能感兴趣的:(web,velocity,word,excel,模版)