使用freemaker模板生成word文档

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dushanlitian/article/details/72190168

这是请求方法,一般的action,controller,特殊的地方是不要有返回值,因为打印输出的文档就是输出


@Action(value = "/jz/card/exportDoc", results = { @Result(name = "success",type = "stream")})

    public void  exportDoc() throws Exception{
 

businessid =  (String)session.get("businessid");
Long bid=(businessid==null?0:Long.valueOf(businessid));
list=redemptionCardService.getCardByStatus(status,printStatus,bid);
//修改希望保留到数据库的字段//此处修改卡券的打印状态
for (RedemptionCard rcard : list)
{
rcard.setPrintStatus(1);
}
redemptionCardService.batchSave(list);
//下面处理不希望保留到数据库的字段,但是因为要打印到word需要特殊处理的内容,譬如希望抓取本地图片绝对路径
root=PropertyHolder.get().getServerPath();
     /*   for (RedemptionCard rcard : list)
{
StringBuilder sb=new StringBuilder();
//upload文件夹相对目录
String ewm=rcard.getEwm();
 //获取tomcat项目目录的webapps根目录的root,然后添加到相对路径前面
     sb.append(root).append(ewm); 
rcard.setEwm(sb.toString());
}*/
      //创建一个导出word文档工具对象
ExportDoc exportDoc = new ExportDoc(); 
//要填入模本的数据对象,放在map中
Map<String, Object> rootMap = new HashMap<String, Object>();
rootMap.put("list", list);
rootMap.put("root", root);
 String ftlModelPath="/com/canyou/template/";//模板类所在包路径
 String ftlName="cardExport.ftl";//导出word形式的ftl模板名称
 //传入参数、工具对象将创建word文档
 exportDoc.create(rootMap,response,ftlModelPath,ftlName);
   

 } 



下面是关键的导出工具类exportDoc 封装了转换的方法

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.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import com.thoughtworks.xstream.core.util.Base64Encoder;
import freemarker.template.Configuration;
import freemarker.template.Template;




/** @Title: create 创建并导出word文档,response输出到浏览器
 *  @author 杜闪
 * @ClassName:ExportDoc
 * @Description: 导出提货卡二维码到word文档中,
 * @date:2017-5-11 下午3:52:12
 * @version 1.0
 */
public class ExportDoc {


    private Configuration configuration = null;
//构造函数初始化配置
    public ExportDoc() {
        configuration = new Configuration();
        configuration.setDefaultEncoding("UTF-8");
    }


    
    /**
     *
     * @Title: create 创建word文档,response输出到浏览器
     * @Description: @param 说明:(注意dataMap里存放的数据Key值要与ftl模板中的参数相对应,
     *  @ftlModelPath ftl模板的类路径,一般以ftl后缀结束
     * @ftlName ftl模板名称)
     * @param @dataMap 
     * @param @param response
     * @param @ftlModelPath 
     * @param @ftlName 
     * @param @throws Exception
     * @return Boolean
     *  // 模板放在com.canyou.template包下面,通过ClassForTemplateLoading装载
    //configuration.setDirectoryForTemplateLoading(new File("/views/redemption/"));//存放在文档目录里装载也可以
    //自己在项目中放入模板位置,完整的包名称,设置要装载的模板路径
     * @throws
     */
    public void create(Map<String, Object> rootMap, HttpServletResponse response,String ftlModelPath,String ftlName)
            throws Exception {
    //设置要装载的模板名称
        configuration.setClassForTemplateLoading(this.getClass(), ftlModelPath); 
        Template template = configuration.getTemplate(ftlName);
       //生成文件名称,日期字符串
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String fileName = sdf.format(new Date());
        
        File outFile = new File(fileName.replace(".", "")+".doc");
        
        if (!outFile.exists()) {
            outFile.createNewFile();
        }
        //输出路径
        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"));
        //模板处理数据
        template.process(rootMap, out);
        out.close();
        
        //导出时有界面,可选择下载路径,response输出
        response.addHeader("Content-Disposition", "attachment;filename=" + new String(outFile.getName().getBytes("utf-8"), "utf-8"));
        response.setContentType("application/msword");
     
        OutputStream out1 = null;
        InputStream in = null;
        
        try {
            in = new FileInputStream(outFile);
            BufferedInputStream bis = new BufferedInputStream(in);
          //response输出流
            out1 = response.getOutputStream();
            
            BufferedOutputStream bos = new BufferedOutputStream(out1);


            byte[] buff = new byte[1024];
            int bytesRead=0;
            while (-1 != (bytesRead = bis.read(buff))) {
                bos.write(buff, 0, bytesRead);
            }
           
            bos.flush();
            bos.close();
            bis.close();
        } catch (Exception e) {
            e.printStackTrace();
            
        }


        finally {
            if (out1 != null)
                out1.close();
            if (in != null)
                in.close();
        }
        
       
    }
   
    /**
     * 
     * @Title: getImageString 
     * @Description: 将本地、网络图片转换成BASE64字符串
     * @param @param filename
     * @param @return
     * @param @throws IOException
     * @return String
     * @throws
     */
    public static String getImageString(String imageUrl) throws IOException {
        
      InputStream in = null;
        
        InputStream dis = null;
        byte[] data = null;
        
        try {
            
            //方法一、将网络图片导入word
            /*URL url = new URL(imageUrl);
            //打开网络输入流
            URLConnection conn =  url.openConnection();
            
            //设置超时间为3秒  
            //conn.setConnectTimeout(3*1000);  
            //防止屏蔽程序抓取而返回403错误  
            //conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");  
      
            //得到输入流  
            InputStream inputStream = conn.getInputStream();    
            //获取自己数组  
            data = readInputStream(inputStream); */
         
            //方法二、将本地图片导入word,打开本地输入流
            in = new FileInputStream(imageUrl);
            data = new byte[in.available()];
            in.read(data);
            in.close();
          
            
        } catch (IOException e) {
            throw e;
        } finally {
            if (dis != null)
                dis.close();
        }
        
        Base64Encoder encoder = new Base64Encoder();
        
        return data != null ? encoder.encode(data) : "";


    }
    
    /**
     * 
     * @Title: readInputStream 
     * @Description: 将网络图片流转换成数组 
     * @param @param inputStream
     * @param @return
     * @param @throws IOException
     * @return byte[]
     * @throws
     */
    public static  byte[] readInputStream(InputStream inputStream) throws IOException {    
        byte[] buffer = new byte[1024];    
        int len = 0;    
        ByteArrayOutputStream bos = new ByteArrayOutputStream();    
        while((len = inputStream.read(buffer)) != -1) {    
            bos.write(buffer, 0, len);    
        }    
        bos.close();    
        return bos.toByteArray();    
    }    


    /**
     * @Title: downloadImg 
     * @Description: 网络图片下載到本地 
     * @param @param imgUrl:网络图片,http开头
     * @param @return 返回下载到本地的图片路径
     * @param @throws Exception
     * @return String
     * @throws
     */
    public String downloadImg(String imgUrl) throws Exception{  
        
        // 构造URL  
        URL url = new URL(imgUrl);  
        // 打开连接  
        URLConnection con = url.openConnection();  
        //设置请求超时为5s  
        con.setConnectTimeout(5*1000);  
        // 输入流  
        InputStream is = con.getInputStream();  
      
        // 1K的数据缓冲  
        byte[] bs = new byte[1024];  
        // 读取到的数据长度  
        int len;  
        
        //创建下载路径
        String savePath = "D://download//";
        String filename =  ".jpg";
        String returnUrl = savePath+filename;
        
        File sf = new File(savePath);  
        if(!sf.exists()){  
            sf.mkdirs();  
        }  
        
        // 输出的文件流  
        OutputStream os = new FileOutputStream(sf.getPath()+"\\"+filename);  
        // 开始读取  
        while ((len = is.read(bs)) != -1) {  
            os.write(bs, 0, len);  
        }  
        // 完毕,关闭所有链接 
        os.flush();
        os.close();  
        is.close();   
        
        return returnUrl;
    }
    
    
}


最后创建一个freemaker模板存放我们需要打印的内容,打印的key要和map里面一样才行,有时候需要根路径的时候,根路径要放到map里,map里存放list和root

这是我要打印的二维码链接验证的东西,把卡券卖给用户后,用户扫码填写密码就可以来验证了,这样可以一次打印多张二维码。

<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body style="text-align:left;margin-top:3%;background-color:#eee;margin-left:3%;">


<#list list as card>
         <div class="tip-dialog">
            <p>微信扫码验证卡券</p>
            <p>提货卡号:${card.cardnumber!}</p>
            <#if card.status==0>
            未验证
            <#else>
             验证时间:${card.verifyTime!}
            </#if>
            <div class="erweima_box">
            <img width="200px" src="${root}${card.ewm!}">
            </div>
<p>提货卡密码:${card.cardpassword!}</p>

        </div>
        <HR align=center style="border:3 double #987cb9" width="80%" color=#987cb9 SIZE=3>
</#list>

</body>
</html>



猜你喜欢

转载自blog.csdn.net/dushanlitian/article/details/72190168