• java 下载word freemaker


      网上有很多优质的博文了,这里这篇博客就是记录一下字自己,写demo的历程,坑和收获

      在java程序中下载word 有6中方式,此处省略(嘻嘻),不过大家公认的是 freemaker 和 PageOffice

      本篇文章是用的freemaker。

      下载word 的大体思路是,制作模板,封装数据,导出

     一 制作模板  

      很简单的模板

     1 首先新建word

    2 文件另存为 word .xml格式。

    3 用 notepad++  或者ideal打开xml文件(我这里推荐用ideal,看着舒服些)关于格式化xml,可以在点击开的链接上格式化xml  

      格式化xml之后,把文件保存为ftl格式,重新再在编辑器打开。

      找到其中${user.username}和${user.password},仔细分析该ftl文件可以发现,在word文档中表格的每一行在xml文件中即为一个<w:tr></w:tr>标签,而在该标签中,每一个<w:tc></w:tc>则对应一个单元格。了解这个之后,我们就要使用ftl语法对该模板文件进行改造。这里我们需要导出的是一个用户列表的文件,每个用户包含一个用户名和密码,那么这里用户所在的这一行(<w:tr></w:tr>)就需要使用ftl中的<#list></#list>标签包含起来:

    <#list users as user> 
    <w:tr> 
    <w:tc> 
    ... 
    用户名: 
    ... 
    </w:tc> 
    <w:tc> 
    ... 
    ${user.username} 
    ... 
    </w:tc> 
    <w:tc> 
    ... 
    密码: 
    ... 
    </w:tc> 
    <w:tc> 
    ... 
    ${user.password} 
    ... 
    </w:tc> 
    </w:tr> 
    </#list>

            到此为止,我们的ftl模板就制作完毕了。

    二  接下来我们创建后台服务端的代码

      代码分为3部分 

      1  WordUtil   为freemaker模板设置相关的内容。

     2 DownloadUtil  为下载的 工具类。

     3自己封装自己的数据,一般是就是从数据库中查询出的数据。。

     下面贴出的代码时service层和util工具类 ,controller 没内容就不贴了。

    @Service
    public class DownLoadServiceImpl implements DownLoadService {
    
    
        @Override
        public void downLoad(HttpServletResponse response, String wordName) {
            Map<?, ?> root = initData();  //数据源对象
            String template = "/template/UserList.ftl";  //模板文件的地址
            String path = "E:\UserList.doc";  //生成的word文档的输出地址
            ByteArrayOutputStream byteArrayOutputStream = WordUtil.process(root, template);
            try {
                DownLoadUtil.download(byteArrayOutputStream,response,wordName);
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
    
    
        private Map<?, ?> initData() {
            Map<String, Object> root = new HashMap<String, Object>();
    
            List<User> users = new ArrayList<User>();
            User zhangsan = new User("小姐姐", "倾国倾城");
            User lisi = new User("沉鱼落雁", "闭月羞花");
            //User wangwu = new User("王五", "789");
            users.add(zhangsan);
            users.add(lisi);
            //users.add(wangwu);
    
            root.put("users", users);
            root.put("title", "用户列表");
    
            return root;
        }
    }
    public class DownLoadUtil {
    
    
        /**
         * @param byteArrayOutputStream 将文件内容写入ByteArrayOutputStream
         * @param response HttpServletResponse  写入response
         * @param returnName 返回的文件名
         */
        public static void download(ByteArrayOutputStream byteArrayOutputStream, HttpServletResponse response, String returnName) throws IOException {
            response.setContentType("application/msword");
            response.setHeader("Content-Disposition", "attachment; filename=" + returnName);
            response.setContentLength(byteArrayOutputStream.size());
            OutputStream outputstream = response.getOutputStream();         //取得输出流
            byteArrayOutputStream.writeTo(outputstream);                    //写到输出流
            byteArrayOutputStream.close();                                  //关闭
            outputstream.flush();                                           //刷数据
        }
    }
    public class WordUtil {
    
        private static Configuration configuration = null;
    
        private WordUtil() {
            throw new AssertionError();
        }
    
        /**
         * 根据模板生成相应的文件
         * @param root 保存数据的map
         * @param template 模板文件的地址
         * @param
         * @return
         */
        public static synchronized ByteArrayOutputStream process(Map<?, ?> root, String template) {
    
            if (null == root ) {
                throw new RuntimeException("数据不能为空");
            }
    
            if (null == template) {
                throw new RuntimeException("模板文件不能为空");
            }
    
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            String templatePath = template.substring(0, template.lastIndexOf("/"));
            String templateName = template.substring(template.lastIndexOf("/") + 1, template.length());
    
            if (null == configuration) {
                configuration = new Configuration(Configuration.VERSION_2_3_23);  // 这里Configurantion对象不能有两个,否则多线程访问会报错
                configuration.setDefaultEncoding("utf-8");
                configuration.setClassicCompatible(true);
            }
            configuration.setClassForTemplateLoading(WordUtil.class, templatePath);
    
            Template t = null;
            try {
                t = configuration.getTemplate(templateName);
                Writer w = new BufferedWriter(new OutputStreamWriter(outputStream, "utf-8"));
                t.process(root, w);  // 这里w是一个输出地址,可以输出到任何位置,如控制台,网页等
                w.close();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            return outputStream;
        }
    
    }

    下面是实体类

    public class User {
    
        private String name;
    
        private String password;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public User(String name, String password) {
            this.name = name;
            this.password = password;
        }
    
        public User() {
        }
    
      
    }
            <dependency>
                <groupId>org.freemarker</groupId>
                <artifactId>freemarker</artifactId>
                <version>2.3.28</version>
            </dependency>

    做个各个demo 参考了好几位博友的文章,在此表示感谢。

     参考链接:https://www.cnblogs.com/vcmq/p/9484362.html

        http://itindex.net/detail/55080-springboot-freemarker-%E6%A0%BC%E5%BC%8F

    下面demo源码:链接: https://pan.baidu.com/s/1-eVO-YgBTw-xTxA4Q4EIdg 提取码: 5g8h 

  • 相关阅读:
    C# private public protected internal
    VS2008 的计算代码度量值
    vs2008安装失败
    DataGridView 结束编辑不用鼠标点其它地方
    常见的C #单元测试工具介绍
    只运行一个实例的写法
    C# WebBrowser控件禁用超链接转向、脚本错误提示、默认右键菜单和快捷键
    C#中的深复制和浅复制
    Prototype源码浅析——String部分(二)
    从URL中提取参数与将对象转换为URL查询参数
  • 原文地址:https://www.cnblogs.com/prader6/p/10562156.html
Copyright © 2020-2023  润新知