资讯专栏INFORMATION COLUMN

【freemaker实现导出word②】代码实现导出word(包括导出list数据和导出图片到wor

bitkylin / 3501人阅读

摘要:前面文章已经分享了如何创建导出需要用到的模板了,接下来这里要给大家分享的是如何用后台制作导出的代码工具和实现。可以重,数据库装载。

前面文章已经分享了如何创建导出word需要用到的xml/ftl模板了,接下来这里要给大家分享的是如何用后台制作导出word的代码工具和controller实现。

1、首先是工具类,没有工具,谈何实现呢?下面贴我这边导出word的utils,大家可以直接复制粘贴到你们项目就可以引用了。

package com.*.util;

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.Map;

import javax.servlet.http.HttpServletRequest;

import Decoder.BASE64Encoder;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;

/**
 * 类名称:DocUtil
 * 类描述:导出word工具类
 */
public class DocUtil {
    public Configuration configure=null;
    
    public DocUtil(){
        configure= new Configuration(Configuration.getVersion());
        configure.setDefaultEncoding("utf-8");
    }
    /**
     * 根据Doc模板生成word文件
     * @param dataMap 需要填入模板的数据
     * @param downloadType 文件名称
     * @param savePath 保存路径
     */
    public File createDoc(Map dataMap,String modelPath,String downloadType,HttpServletRequest request){
        String name = "temp" + (int) (Math.random() * 100000) + ".doc";  
        File f = new File(name); 
        //加载需要装填的模板
        Template template=null;
        try {
            
            //设置模板装置方法和路径,FreeMarker支持多种模板装载方法。可以重servlet,classpath,数据库装载。
            //加载模板文件,放在/uploadFiles/file/demoDoc下
            configure.setServletContextForTemplateLoading(request.getServletContext(), modelPath);
            //设置对象包装器
//            configure.setObjectWrapper(new DefaultObjectWrapper());
            //设置异常处理器
            configure.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
            //定义Template对象,注意模板类型名字与downloadType要一致
            template=configure.getTemplate(downloadType);
           
            Writer out = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
            template.process(dataMap, out);
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        }
         return f;  
    }
    
    /**
     * 根据Doc模板生成word文件
     * @param dataMap 需要填入模板的数据
     * @param downloadType 文件名称
     * @param savePath 保存路径
     */
    public void createXls(Map dataMap,String downloadType,String webPath,String fileName,String savePath){
        System.out.println(savePath.substring(savePath.length()-1));
        if(savePath.substring(savePath.length()-1).equals(File.separator)) {
            savePath = savePath + "uploadFiles" + File.separator + "file" + File.separator + "jdhDailySheet"+ File.separator;
        }else {
            savePath = savePath  + File.separator + "uploadFiles" + File.separator + "file" + File.separator + "jdhDailySheet"+ File.separator;
        }
        File f = new File(savePath+fileName); 
        
        //加载需要装填的模板
        Template template=null;
        try {
            if(!f.getParentFile().exists()){
                f.getParentFile().mkdirs();
            }
            if(f.exists() && f.isFile()){
                f.delete();
            } else {
                f.createNewFile();
            }
            
            //设置模板装置方法和路径,FreeMarker支持多种模板装载方法。可以重servlet,classpath,数据库装载。
            //加载模板文件,放在/uploadFiles/file/demoDoc下
            configure.setDirectoryForTemplateLoading(new File(webPath + "uploadFiles" + File.separator + "file" + File.separator));
            //设置对象包装器
//            configure.setObjectWrapper(new DefaultObjectWrapper());
            //设置异常处理器
            configure.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
            //定义Template对象,注意模板类型名字与downloadType要一致
            template=configure.getTemplate(downloadType);
           
            Writer out = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
            template.process(dataMap, out);
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        }
    }
}

2、接下来是处理图片的工具类,这里导出word包含导出图片到word,所以需要对图片进行处理,是怎么个原理呢,在这里和大家简单介绍下,具体在后续我会具体详细另外写一篇文章分享。
(1)图片我们可以在前台将要的图片转成base64编码,然后提交给后台接收
(2)后台接收base64编码后使用工具类将base64解码成图片然后保存到本地中
(3)在要导出word的时候读取下本地存储图片的路径然后把图片导出来就行了。
工具类如下:同第一条一样可直接复制到你们项目中使用。

package com.*.util;
import java.awt.image.BufferedImage;
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.util.UUID;
import javax.imageio.ImageIO;
import Decoder.BASE64Decoder;
import Decoder.BASE64Encoder;


/**
 * 类名称:ImageUtil
 * 类描述:图片处理工具类
 */
public class ImageUtil {
    
     /**
      * 从path这个地址获取一张图片然后转为base64码
      * @param imgName  图片的名字 如:123.png(是带后缀的)
      * @param path     123.png图片存放的路径
      * @return
      * @throws Exception
      */
     public static String getImageFromServer(String imgName,String path)throws Exception{
      BASE64Encoder encoder = new BASE64Encoder();
      File f = new File(path+imgName);
            if(!f.exists()){
        f.createNewFile();
            }
            BufferedImage bi = ImageIO.read(f);    
            ByteArrayOutputStream baos = new ByteArrayOutputStream();    
            ImageIO.write(bi, "png", baos);    
            byte[] bytes = baos.toByteArray();    
            return encoder.encodeBuffer(bytes).trim();      
     }
     
     /**
      * 将一个base64转换成图片保存在  path文件夹下  ,命名随机
      * @param base64String
      * @param path  是一个文件夹路径
      * @param imgName 图片名字(没有后缀)
      * @throws Exception
      */
     public static String savePictoServer(String base64String,String path)throws Exception{
        
         BASE64Decoder decoder = new BASE64Decoder();
         //要把+在上传时变成的空格再改为+
         base64String = base64String.replaceAll(" ", "+");
         //去掉“data:image/png;base64,”后面才是base64编码,去掉之后才能解析
         base64String = base64String.replace("data:image/png;base64,","");
         //在本地指定位置建立文件夹,path由控制台那边进行定义
         String realPath = path+"/"+"echarts";
         File dir=new File(realPath);
         if(!dir.exists()){
          dir.mkdirs();
         }
         String fileName=path+""+"echarts"+""+UUID.randomUUID().toString()+".png";
         try {  
             byte[] buffer = decoder.decodeBuffer(base64String);  
             OutputStream os = new FileOutputStream(fileName);
             for(int i =0;i

3、接下来就要介绍下在控制台怎么使用工具类实现导出word啦,详细细节看注释

static String MODELPATH = "/uploadFiles/…";

@RequestMapping(value = { "/downloadDoc" }, produces = "text/html;charset=UTF-8")
public void downloadDoc(HttpServletRequest request, HttpServletResponse response) {
    //引入导出word的工具类
    DocUtil docUtil = new DocUtil();
    //引入处理图片的工具类,包含将base64编码解析为图片并保存本地,获取图片本地路径
    ImageUtil imageUtil = new ImageUtil();
    //建立map存储所要导出到word的各种数据和图像,不能使用自己项目封装的类型,例如PageData
    Map dataMap = new HashMap(); 
    
    /*
     *  这一步,请求所需要导出到word的数据quotaList,把你们的数据处理放到这里就行了
     */
    
    
    //这一步,进行图片的处理,获取前台传过来的图片base64编码,在利用工具类解析图片保存到本地,然后利用工具类获取图片本地地址
    String barBase64Info = request.getParameter("barBase64Info");
    String path = "D:";
    String image1 = ImageUtil.savePictoServer(barBase64Info, path);
    image1  = imageUtil.getImageStr(image1);
    
    //将以上处理的数据都存入dataMap 中
    
    //以下都是进行word文件的处理,直接复制,然后细节按需修改就行了
    request.setCharacterEncoding("utf-8");
    File file = null;
    InputStream fin = null;
    OutputStream out = null;
    String filename = "文件名.doc";
        //dataMap是上面处理完的数据,MODELPATH是模板文件的存储路径,"模板.xml"是相应的模板文件
    file = docUtil.createDoc(dataMap, MODELPATH, "模板.xml", request);
    fin = new FileInputStream(file);
    response.setContentLength((int) file.length());//需要传递这个长度,不然下载文件后,打开提示内容有问题,如docx等
    response.setCharacterEncoding("utf-8");
    response.setContentType("application/msword");
    response.setHeader("Content-disposition", "attachment;filename=" + new String(filename.getBytes("utf-8"), "iso8859-1"));
    out = response.getOutputStream();
    byte[] buffer = new byte[1024]; // 缓冲区  
    int bytesToRead = -1;
    // 通过循环将读入的Word文件的内容输出到浏览器中  
    while ((bytesToRead = fin.read(buffer)) != -1) {
        out.write(buffer, 0, bytesToRead);
    }
    if (fin != null)
        fin.close();
    if (out != null)
        out.close();
    if (file != null)
        file.delete(); // 删除临时文件
    
    
}

注意:模板的list在后台构造的时候必须是实体类或者有属性类型的,如果是自己项目封装的类型,如在我的项目中有自己封装的PageData类型的,在模板的list是识别不出list里面的数据的。

各位看官看在本仙女这么辛苦分享的份上随手点个赞呗^_^!!!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/67885.html

相关文章

  • freemaker实现导出word①】创建xml/ftl模板

    摘要:在项目中,往往很多时候需要我们实现将数据导出到文档中,但是导出首要做法就是创建模板,没有模板,请求出来的数据就没有可以存放和显示的地方。代码实现导出请看后续文章。 在javaweb项目中,往往很多时候需要我们实现将数据导出到word文档中,但是导出word首要做法就是创建模板,没有模板,请求出来的数据就没有可以存放和显示的地方。导出的模板需要xml或者ftl格式的文件。 新建word文...

    Kross 评论0 收藏0
  • freemaker实现导出word③】详解将echarts的图片word

    摘要:前面介绍了导出到的代码实现,详见这里,里面有一部分涉及导出图片到,在这里我再另外做一个详细的介绍。在前台用将生成的图片转成编码,提交给后台。 前面介绍了导出到word的代码实现,详见这里,里面有一部分涉及导出图片到word,在这里我再另外做一个详细的介绍。是这样的,我项目有个功能,里面就涉及到要将echarts形成的柱状图或者地图之类的图表导出到word,在网上找了很久,都是说将图片转...

    flyer_dev 评论0 收藏0
  • freemaker实现导出word③】详解将echarts的图片word

    摘要:前面介绍了导出到的代码实现,详见这里,里面有一部分涉及导出图片到,在这里我再另外做一个详细的介绍。在前台用将生成的图片转成编码,提交给后台。 前面介绍了导出到word的代码实现,详见这里,里面有一部分涉及导出图片到word,在这里我再另外做一个详细的介绍。是这样的,我项目有个功能,里面就涉及到要将echarts形成的柱状图或者地图之类的图表导出到word,在网上找了很久,都是说将图片转...

    endless_road 评论0 收藏0
  • FineReport中JS如何自定义按钮导出

    FineReport支持多种不同的导出方式,直接使用FineReport内置导出按钮可以非常快捷方便的来对各种格式的输出,但是我们在web页面集成中的时候,往往只想将报表内容嵌入到iframe中,而工具栏以及工具栏上的按钮都会隐藏掉,而使用web页面自定义的按钮,那么,此时,这种自定义按钮如何实现导出呢? showImg(https://segmentfault.com/img/bVJR1H?w=...

    wujl596 评论0 收藏0
  • POI如何高效导出百万级Excel数据

    摘要:阅读原文如何高效导出百万级数据在一个具有统计功能的系统中,导出功能几乎是一定的,如何导出导出的数据有多少如何高效的导出简介什么是就不用介绍了,这里主要说明不同版本下每个下的行列限制。 阅读原文:POI如何高效导出百万级Excel数据? 在一个具有统计功能的系统中,导出excel功能几乎是一定的,如何导出excel?导出的数据有多少?如何高效的导出? Excel简介什么是excel就不用...

    lemanli 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<