zoukankan      html  css  js  c++  java
  • Java用freemarker导出Word 文档

    1.用Microsoft Office Word打开word原件;

    2.把需要动态修改的内容替换成***,如果有图片,尽量选择较小的图片几十K左右,并调整好位置;

    3.另存为,选择保存类型Word 2003 XML 文档(*.xml)【这里说一下为什么用Microsoft Office Word打开且要保存为Word 2003XML,本人亲测,用WPS找不到Word 2003XML选项,如果保存为Word XML,会有兼容问题,避免出现导出的word文档不能用Word 2003打开的问题】;

    4.用Firstobject free XML editor打开文件,选择Tools下的Indent【或者按快捷键F8】格式化文件内容。左边是文档结构,右边是文档内容;

    5. 将文档内容中需要动态修改内容的地方,换成freemarker的标识。其实就是Map<String, Object>中key,如${landName};

    6.在加入了图片占位的地方,会看到一片base64编码后的代码,把base64替换成${image},也就是Map<String, Object>中key,值必须要处理成base64;

      代码如:<w:binData w:name="wordml://自定义.png" xml:space="preserve">${image}</w:binData>

      注意:“>${image}<”这尖括号中间不能加任何其他的诸如空格,tab,换行等符号。

      如果需要循环,则使用:<#list maps as map></#list>  maps是Map<String, Object>中key,值为数组,map为自定义;

    7. 标识替换完之后,模板就弄完了,另存为.ftl后缀文件即可。注意:一定不要用word打开ftl模板文件,否则xml内容会发生变化,导致前面的工作白做了。

    导出到本地:

    import java.io.BufferedWriter;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.io.OutputStreamWriter;
    import java.io.Writer;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import com.aspose.words.Document;
    import com.aspose.words.License;
    import com.aspose.words.SaveFormat;
    
    import freemarker.template.Configuration;
    import freemarker.template.Template;
    import sun.misc.BASE64Encoder;
    
    public class WordTest {
    
        // 此目录路径 要求 完整的路径,并且 windows 不能以 /开头 如 : /c:/xxx/xxx
        static URL      freemarker     = WordTest.class.getClassLoader().getResource("freemarker");
        static String freemarkerPath = freemarker != null ? new File(freemarker.getFile()).getAbsolutePath() : new File("freemarker").getAbsolutePath();
    
        //去除PDF水印文件
        static URL aspose = WordTest.class.getClassLoader().getResource("freemarker");
        static String asposePath = freemarker != null ? new File(freemarker.getFile()).getAbsolutePath() : new File("freemarker").getAbsolutePath();
        
        public static void main(String[] args) {
            WordTest wordTest = new WordTest();
            SimpleDateFormat sdf = new SimpleDateFormat("MMdd");
            SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日");
            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日HH时mm分");
            SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy.MM.dd");
            Date date = new Date();
            // 要填充的数据, 注意map的key要和word中${xxx}的xxx一致
            Map<String, Object> dataMap = new HashMap<String, Object>();
            List<Object> list = new ArrayList<Object>();
            for (int i = 0; i < 10; i++) {
                WordUser word = new WordUser();
                word.setImgEntityId(new Long(i));
                word.setImgEntityName("目标" + i);
                word.setLeftUpLatitude(231.342 + i * 10);
                word.setLeftUpLongitude(234.32425 + i * 10);
                list.add(word);
            }
            dataMap.put("date", sdf.format(date));
            dataMap.put("dateTime", sdf1.format(date));
            dataMap.put("organicName", "国有控股");
            dataMap.put("picCreateTime", sdf1.format(new Date()));
            dataMap.put("picCreateTime2", sdf2.format(new Date()));
            dataMap.put("picCreateTime3", sdf3.format(new Date()));
            dataMap.put("imgTypeName", "E-22战斗机");
            dataMap.put("imgRootName", "无人机");
            dataMap.put("imgEntity", "飞机、战斗机、歼-22、隐形战机");
            dataMap.put("list", list);
            
            dataMap.put("station2", "先空下来");
            dataMap.put("coordinate", "先空下来");
            dataMap.put("thematicWords", "境外低轨侦察卫星");
    
            dataMap.put("imgStr", wordTest.getImageStr2("http://47.93.82.37:8180/1.png"));
            // dataMap.put("imgStr", wordTest.getImageStr("/Users/macbook/Documents/1.png"));
            try {
                wordTest.exportSimpleWord(dataMap);
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public void exportSimpleWord(Map<String, Object> dataMap) throws Exception {
            // Configuration用于读取ftl文件
            Configuration configuration = new Configuration();
            configuration.setDefaultEncoding("utf-8");
    
            /*
             * 以下是两种指定ftl文件所在目录路径的方式, 注意这两种方式都是 指定ftl文件所在目录的路径,而不是ftl文件的路径
             */
            // 指定路径的第一种方式(根据某个类的相对路径指定)
            // configuration.setClassForTemplateLoading(this.getClass(),"");
    
            // 指定路径的第二种方式,我的路径是C:/a.ftl
            configuration.setDirectoryForTemplateLoading(new File(freemarkerPath));
    
            // 创建临时文件
            // File outFile = File.createTempFile("pattern", ".docx");
    
            // 输出文档路径及名称
            File outFile = new File("/Users/macbook/Documents/test1.doc");
    
            // 以utf-8的编码读取模版ftl文件
            Template t = configuration.getTemplate("test4.ftl", "utf-8");
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"), 10240);
            t.process(dataMap, out);
            out.close();
            // 删除临时文件
            // outFile.delete();
    
            // word文档转换成PDF
            String wordPath = "/Users/macbook/Documents/test1.doc";
            doc2pdf(wordPath);
        }
    // 获取图片流
        public String getImageStr2(String imgPath) {
            ByteArrayOutputStream data = new ByteArrayOutputStream();
            try {
                URL url = new URL(imgPath);
                byte[] by = new byte[1024];
                // 创建链接
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setConnectTimeout(60 * 1000);
                InputStream is = conn.getInputStream();
                // 将内容读取内存中
                int len = -1;
                while ((len = is.read(by)) != -1) {
                    data.write(by, 0, len);
                }
                // 关闭流
                is.close();
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            BASE64Encoder encoder = new BASE64Encoder();
            return encoder.encode(data.toByteArray());
        }
    
        // word转PDF
        public void doc2pdf(String wordPath) {
    //         if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
    //         return;
    //         }
            try {
                long old = System.currentTimeMillis();
                File file = new File("/Users/macbook/Documents/test1.pdf"); // 新建一个空白pdf文档
                FileOutputStream os = new FileOutputStream(file);
                Document doc = new Document(wordPath); // Address是将要被转化的word文档
                doc.save(os, SaveFormat.PDF);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,
                                             // EPUB, XPS, SWF 相互转换
                long now = System.currentTimeMillis();
                System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒"); // 转化用时
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        // 验证License 若不验证则转化出的pdf文档会有水印产生
        public boolean getLicense() {
            boolean result = false;
            try {
                //InputStream is = WordTest.class.getClassLoader().getResourceAsStream("license.xml"); // license.xml应放在..WebRootWEB-INFclasses路径下
                InputStream is = new FileInputStream(asposePath+"/license2.xml");
                License aposeLic = new License();
                aposeLic.setLicense(is);
                result = true;
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
    
    }

    浏览器直接下载(get请求):

    @RequestMapping(value="/investigation/exportWord",method = RequestMethod.GET)
        @ResponseBody   
        public void exportWord(HttpServletRequest request, HttpServletResponse response) {
            JSONObject result = new JSONObject();
            Long imgPicId = Long.valueOf(request.getParameter("imgPicId"));
            // 要填充的数据, 注意map的key要和word中${xxx}的xxx一致
            Map<String, Object> dataMap = exportSimpleWordService.exportSimpleWord(imgPicId);
            //获取图片类型名称作为文件名
            String imgTypeName = (String) dataMap.get("imgTypeName");
            
            // Configuration用于读取ftl文件
            Configuration configuration = new Configuration();
            configuration.setDefaultEncoding("utf-8");
    
            // 指定路径我的路径是C:/a.ftl
            try {
                configuration.setDirectoryForTemplateLoading(new File(freemarkerPath));// 指定ftl所在目录,根据自己的改
                response.setContentType("application/msword");
                response.setHeader("Content-Disposition", "attachment;filename="" + new String((imgTypeName+"侦查要报.doc").getBytes("GBK"), "iso8859-1") + """);
                response.setCharacterEncoding("utf-8");// 此句非常关键,不然word文档全是乱码
                PrintWriter out = response.getWriter();
                Template t = configuration.getTemplate("investigation.ftl", "utf-8");// 以utf-8的编码读取ftl文件
                t.process(dataMap, out);
                out.close();
            }
            catch (Exception e) {
                logger.error("转换成word文档业务服务异常!", e);
                result.put("respCode", BaseRspConstants.RSP_CODE_FAILUR);
                result.put("respDesc", BaseRspConstants.RSP_DESC_FAILUR);  
            }
    
            // return jsonObject;
        }
  • 相关阅读:
    计算机二进制总结
    java-集合排序,队列,散列表map以及如何遍历
    java-Collection,List简单使用与方法/(集合使用-中)
    java-Date类与集合(上)
    java-正则、object中的两个方法的使用
    java-注释、API之字符串(String)
    Java-面向对象三大特征、设计规则
    java-多态、内部类
    java-修饰词、抽象类、抽象方法
    java-重载、包修饰词以及堆栈管理
  • 原文地址:https://www.cnblogs.com/wylblogs/p/word.html
Copyright © 2011-2022 走看看