• JAVAWEB使用FreeMarker利用ftl把含有图片的word模板生成word文档,然后打包成压缩包进行下载


    这是写的另一个导出word方法:https://www.cnblogs.com/pxblog/p/13072711.html

    引入jar包,freemarker.jar、apache-ant-zip-1.8.0.jar(制作压缩包使用)

    下载地址:   https://yvioo.lanzous.com/b00njhxoh    密码:2mcs

    或者maven

    <!-- https://mvnrepository.com/artifact/org.freemarker/freemarker -->
    <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
        <version>2.3.23</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.ant/ant -->
    <dependency>
        <groupId>org.apache.ant</groupId>
        <artifactId>ant</artifactId>
        <version>1.8.0</version>
    </dependency>

    1、准备ftl模板,先在一个word中模板排版好,然后另存为-保存成“Word 2003 XML文档” 后缀名是.xml的文件

    注:模板中的值要使用占位符进行填充 ,如下图所示,“name”名称是根据后台代码来的,这里可以换成自己的

    然后生成.xml文件后,可以利用网上格式化工具格式化看下 生成的模板文件是否正确,占位符“${name}”必须是完整的,中间不能含有其他字符

     如果word模板中含有图片,图片在xml文件中展现的形式是Base64格式的 ,包含在<w:binData>和</w:binData>中,把Base64删掉,替换成占位符,我这里使用的是“${photo}”(<w:binData>和</w:binData>中除了占位符不能有其他代码,也不能换行,主要是下面两个标签内都不能有其他标签)

    如果没有<w:binData>和</w:binData>标签的话,就是在模板中没有把图片放进去,需要把图片也放进去模板中,然后生成xml文件

    <w:binData w:name="wordml://03000001.png" xml:space="preserve">${photo}</w:binData>
    <v:shape id="图片 2" o:spid="_x0000_i1025" type="#_x0000_t75" style="56.5pt;height:93pt;visibility:visible;mso-wrap-style:square"><v:imagedata src="wordml://03000001.png" o:title="touxiangm"/></v:shape>

     如果是多张图片的时候,就在模板文档里面放多张图片,然后看生成的模板样子,内容都是可以循环的,把共同部分拿出来,然后使用<#list>标签进行循环遍历,有些字段循环也是不一样,如下图所示,每个人可能模板不一样。

     

    2、然后把保存的wordExport.xml文件 后缀名改成.ftl文件 

    3、后台代码

    导出word工具类

    WordUtils.javapackage testword;
    import java.io.*;
    import java.util.Map;
    
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import freemarker.template.Configuration;
    import freemarker.template.Template;
    import sun.misc.BASE64Encoder;
    
    public class WordUtils {
        //配置信息,代码本身写的还是很可读的,就不过多注解了
        private static Configuration configuration = null;
        //这里注意的是利用WordUtils的类加载器动态获得模板文件的位置
        // private static final String templateFolder = WordUtils.class.getClassLoader().getResource("../../").getPath() + "WEB-INF/templetes/";
    
    
        public  File exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map map,String title,String templateFolder,String toDirFloder) throws IOException {
            configuration = new Configuration();
            configuration.setDefaultEncoding("utf-8");
            
            //模板所在文件夹
            configuration.setDirectoryForTemplateLoading(new File(templateFolder));
            //wordExport.ftl为模板文件名称
            Template freemarkerTemplate = configuration.getTemplate("wordExport.ftl");
            File file = null;
            InputStream fin = null;
            ServletOutputStream out = null;
            // 调用工具类的createDoc方法生成Word文档
            file = createDoc(map,freemarkerTemplate,title,toDirFloder);
            return file;
        }
    
        private static File createDoc(Map<?, ?> dataMap, Template template,String filename,String toDirFloder) {
    File f
    = new File(toDirFloder+"/"+filename+".doc"); 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; } 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); } }

    导出压缩包工具类

    Zipper.java

    package testword;
    
    import org.apache.commons.lang.StringUtils;
    import org.apache.tools.zip.ZipEntry;
    import org.apache.tools.zip.ZipOutputStream;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.util.Assert;
    
    import java.io.*;
    import java.util.List;
    
    /**
     * 用于制作zip压缩包
     */
    public class Zipper {
        private static final Logger log = LoggerFactory.getLogger(Zipper.class);
    
        /**
         * 制作压缩包
         * 
         */
        public static void zip(OutputStream out, List<FileEntry> fileEntrys,
                String encoding) {
            new Zipper(out, fileEntrys, encoding);
        }
    
        /**
         * 制作压缩包
         * 
         */
        public static void zip(OutputStream out, List<FileEntry> fileEntrys) {
            new Zipper(out, fileEntrys, null);
        }
    
        /**
         * 创建Zipper对象
         * 
         * @param out
         *            输出流
         * @param filter
         *            文件过滤,不过滤可以为null。
         * @param srcFilename
         *            源文件名。可以有多个源文件,如果源文件是目录,那么所有子目录都将被包含。
         */
        protected Zipper(OutputStream out, List<FileEntry> fileEntrys,
                         String encoding) {
            Assert.notEmpty(fileEntrys);
            long begin = System.currentTimeMillis();
            log.debug("开始制作压缩包");
            try {
                try {
                    zipOut = new ZipOutputStream(out);
                    if (!StringUtils.isBlank(encoding)) {
                        log.debug("using encoding: {}", encoding);
                        zipOut.setEncoding(encoding);
                    } else {
                        log.debug("using default encoding");
                    }
                    for (FileEntry fe : fileEntrys) {
                        zip(fe.getFile(), fe.getFilter(), fe.getZipEntry(), fe
                                .getPrefix());
                    }
                } finally {
                    zipOut.close();
                }
            } catch (IOException e) {
                throw new RuntimeException("制作压缩包时,出现IO异常!", e);
            }
            long end = System.currentTimeMillis();
            log.info("制作压缩包成功。耗时:{}ms。", end - begin);
        }
    
        /**
         * 压缩文件
         * 
         * @param srcFile
         *            源文件
         * @param pentry
         *            父ZipEntry
         * @throws IOException
         */
        private void zip(File srcFile, FilenameFilter filter, ZipEntry pentry,
                String prefix) throws IOException {
            ZipEntry entry;
            if (srcFile.isDirectory()) {
                if (pentry == null) {
                    entry = new ZipEntry(srcFile.getName());
                } else {
                    entry = new ZipEntry(pentry.getName() + "/" + srcFile.getName());
                }
                File[] files = srcFile.listFiles(filter);
                for (File f : files) {
                    zip(f, filter, entry, prefix);
                }
            } else {
                if (pentry == null) {
                    entry = new ZipEntry(prefix + srcFile.getName());
                } else {
                    entry = new ZipEntry(pentry.getName() + "/" + prefix
                            + srcFile.getName());
                }
                FileInputStream in;
                try {
                    log.debug("读取文件:{}", srcFile.getAbsolutePath());
                    in = new FileInputStream(srcFile);
                    try {
                        zipOut.putNextEntry(entry);
                        int len;
                        while ((len = in.read(buf)) > 0) {
                            zipOut.write(buf, 0, len);
                        }
                        zipOut.closeEntry();
                    } finally {
                        in.close();
                    }
                } catch (FileNotFoundException e) {
                    throw new RuntimeException("制作压缩包时,源文件不存在:"
                            + srcFile.getAbsolutePath(), e);
                }
            }
        }
    
        private byte[] buf = new byte[1024];
        private ZipOutputStream zipOut;
    
        public static class FileEntry {
            private FilenameFilter filter;
            private String parent;
            private File file;
            private String prefix;
    
            public FileEntry(String parent, String prefix, File file,
                    FilenameFilter filter) {
                this.parent = parent;
                this.prefix = prefix;
                this.file = file;
                this.filter = filter;
            }
    
            public FileEntry(String parent, File file) {
                this.parent = parent;
                this.file = file;
            }
    
            public FileEntry(String parent, String prefix, File file) {
                this(parent, prefix, file, null);
            }
    
            public ZipEntry getZipEntry() {
                if (StringUtils.isBlank(parent)) {
                    return null;
                } else {
                    return new ZipEntry(parent);
                }
            }
    
            public FilenameFilter getFilter() {
                return filter;
            }
    
            public void setFilter(FilenameFilter filter) {
                this.filter = filter;
            }
    
            public String getParent() {
                return parent;
            }
    
            public void setParent(String parent) {
                this.parent = parent;
            }
    
            public File getFile() {
                return file;
            }
    
            public void setFile(File file) {
                this.file = file;
            }
    
            public String getPrefix() {
                if (prefix == null) {
                    return "";
                } else {
                    return prefix;
                }
            }
    
            public void setPrefix(String prefix) {
                this.prefix = prefix;
            }
        }
    }

    使用控制器类

    package testword;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class TestWord {
    
        @RequestMapping("/o_export")
        public void export(HttpServletRequest request, HttpServletResponse response) {
            WordUtils wordUtils = new WordUtils();
            List<Zipper.FileEntry> flist = new ArrayList<Zipper.FileEntry>();
    
            //这里要获取要导出的数据列表集合
            List list = null;
            //模板所在文件夹路径
            String tplDir = null;
    //模板word临时存储的位置
    String toDirFloder=null

          //文件夹不存在,创建文件夹
          File dirFile=new File(toDirFloder);
          if (!dirFile.exists()){
            dirFile.mkdirs();
          }

            //要循环遍历的数据
            for (Object e : list) {
                //导出的word文件名称
                String filename = null;
                try {
                    File file = wordUtils.exportMillCertificateWord(request, response, enrollToMap(e, wordUtils), filename, tplDir, toDirFloder);
                    //这里表示压缩包下会有一个文件夹,名称是“学生信息表”,所有的word文件会放到这个文件夹底下
                    Zipper.FileEntry entry = new Zipper.FileEntry("学生信息表", file);
                    //把文件放到压缩包中
                    flist.add(entry);
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            response.setContentType("application/x-download;charset=UTF-8");
            try {
                //这里的“学生信息表”是压缩包文件名
                response.addHeader("Content-disposition", "filename=" + new String("学生信息表".getBytes("gb2312"), "iso8859-1") + ".zip");
                Zipper.zip(response.getOutputStream(), flist, "GBK");

            //删除word临时保存的文件和文件夹
            File[] files=dirFile.listFiles();
            for (File f:files){
                f.delete();
            }
            dirFile.delete();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    
        public Map enrollToMap(Student s, WordUtils wordUtils) {
            Map map = new HashMap();
    
            //这里的name和sex为模板中占位符的名称 我模板中用的占位符是“${name}”,所以这里map集合的key是name
            map.put("name", s.getName());
            map.put("sex", s.getSex());
    
            //获取图片URL地址后,调用方法生成BASE64格式
            String photoBase64 = wordUtils.getImageBase("图片URL绝对地址");
            map.put("photo", photoBase64);
            return map;
        }
    }
  • 相关阅读:
    @support浏览器兼容判断 以及 @media媒体查询
    关于BFC的总结
    JS—二维数组的创建
    JS—操作符优先级
    JS—事件对象
    JS—事件
    DOM—addEventListener() & removeEventListener()
    高级算法——动态规划(斐波那契函数实例)
    对象字面量的使用
    小程序日历 IOS真机预览问题
  • 原文地址:https://www.cnblogs.com/pxblog/p/12790904.html
Copyright © 2020-2023  润新知