使用freemarker导出html格式的word(调整页边距,页面视图,正常表格样式)

RT,耗费了博主半个月的时间才挤出来的成果,在此记录下开发过程。

博主的另一篇文章改用mht模板导出了包含图片的word:

https://blog.csdn.net/u011099093/article/details/85318212

一、创建freemark模板

首先在web項目中指定目錄下創建一個HTML格式的freemarker模板:




    
    
    
    导出html格式Word演示


Word导出演示

${basicShow!}

<#if lists??> <#list rows as lists>

姓名

年龄

性别

${rows.name!}

${rows.age!}

${rows.gender!}

其中控制打開后展示為頁面視圖的是這一段:


Print
...

百度了好久都沒有百度到相關模板,就寫了個demo先使用html代碼生成一個word,再在word中修改格式,保存。

然後使用NodePad打開保存后的doc文檔分析其中的結構才拼凑成一個格式比較像樣的模板。

控制頁邊距的是以下這一段:

 

使用${param!}引入參數,使用<#if lists??><#list rows as lists>遍歷多條數據插入到模板中;

二、导入数据到模板并生成word

@ResponseBody
    @RequestMapping("/exportWord")
    public Map exportWord(HttpServletRequest request){
        try {
            //遍历獲取所有參數
            Enumeration enu = request.getParameterNames();
            String paraName = null;
            Map parameters = new HashMap<>();
            while (enu.hasMoreElements()) {
                paraName = enu.nextElement();
                parameters.put(paraName, request.getParameter(paraName));
            }

            //準備一段假數據
            Map map = new HashMap<>();
            map.put("basicShow", "這裏展示一段文字。。。啦啦啦");
            List list = new ArrayList<>();
            list.add(new User() {{
                setAge(18);
                setGender("男");
                setName("趙康");
            }});
            list.add(new User() {{
                setAge(34);
                setGender("男");
                setName("劉天");
            }});
            list.add(new User() {{
                setAge(23);
                setGender("女");
                setName("李逵");
            }});
            map.put("lists", list);

            String path = request.getRealPath("/");//獲取項目的根目錄
            ServletContext context = request.getServletContext();

            String filepath = createDoc(path, context, map, "wordOfHtml.ftl", "测试word文档.doc");
            Map resultMap = new HashMap<>();
            resultMap.put("filepath", filepath);
            return resultMap;
        }catch(Exception e){
            e.printStackTrace();
        }
        return null;
    }

    private String createDoc(String path, ServletContext context, Map data, String templateName, String docName) {
        long startTime=System.currentTimeMillis();
        System.out.println("生成word开始。。。");
        Configuration configurationc=new Configuration();
        //设置模板编码格式
        configurationc.setDefaultEncoding("utf-8");
        //设置模板存放的路径
        configurationc.setServletContextForTemplateLoading(context,"freemarkTemplate");
        Template template=null;
        String filepath=null;
        String htmlpath=null;
        try{
            //获取模板设置编码类型
            template=configurationc.getTemplate(templateName,"UTF-8");
            //设置生成word文件的存放路径
            filepath= path+"export"+File.separator;//+"test.doc";
            File file=new File(filepath);
            if(!file.exists()){
//                file.createNewFile();
                file.mkdirs();
            }
            filepath+=docName;
            Writer bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filepath),"utf-8"));
//            BufferedWriter bw=new BufferedWriter(new FileWriter(filepath));
            //替换模板中的占位符并输出
            template.process(data,bw, ObjectWrapper.BEANS_WRAPPER);
            return filepath;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            long end=System.currentTimeMillis();
            System.out.println("用时:"+(end-startTime)/1000+"秒;");
            System.out.println("生成word结束,开始下载。。。");
        }

        return null;
    }

这里为了测试,我直接造的假数据放到Map中,替换模板中对应的参数;

三、导出word

@ResponseBody
    @RequestMapping("/downloadWord")
    public void downloadWord(HttpServletResponse response,String filepath){
        OutputStream os=null;
        FileInputStream inputStream=null;
        System.out.println("开始下载。。。");
        try{
            File file=new File(filepath);
            String filename=new String(file.getName().getBytes("GB2312"),"ISO8859-1");
            //设置输出文件类型为 word.doc
            response.setContentType("application/msword");
            //设置文件名
            response.setHeader("Content-Disposition","attachment;filename="+filename);
            String len=String.valueOf(file.length());
            response.setHeader("Content-length",len);
            os=response.getOutputStream();
            inputStream=new FileInputStream(file);
            byte[] bytes=new byte[1024];
            int i;
            while((i=inputStream.read(bytes))!=-1){
                os.write(bytes,0,i);
            }
            os.flush();
            boolean b=file.delete();
            System.out.println(b+"----------");
        }catch(Exception e){
            e.printStackTrace();
        }
        finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if(os!=null){
                    os.close();
                }
            }catch(Exception e){
                e.printStackTrace();
            }
            System.out.println("下载完成。。。");
        }
    }

前台js:

$.ajax({
        url: _ctx+'/report/common/exportWord',
        data: {},
        type: 'post',
        dataType: 'json',
        success: function (obj) {
            var filepath=obj.filepath;
            console.info(filepath)
            if(filepath!=null){
                var encode2=encodeURIComponent(filepath);
                console.info(encode2)
                console.log(_ctx+'/report/common/downloadWord?'+(new Date().getTime())+"&filepath="+encode2)
                window.location.href=_ctx+'/report/common/downloadWord?'+(new Date().getTime())+"&filepath="+encode2;
            }else{
                alert("下载word失败!");
            }
        }
    })

 

效果:

 

使用freemarker导出html格式的word(调整页边距,页面视图,正常表格样式)_第1张图片

使用nodepad打开word,发现其实格式还是html:

使用freemarker导出html格式的word(调整页边距,页面视图,正常表格样式)_第2张图片

所以如果需要什么样式可以直接在word中修改,然后保存,使用记事本打开就可以看到对应的样式,希望对各位小伙伴有所帮助!

-------------------------------------------------华丽的分割线-----------------------------------------------------

(原创文档,转载请注明出处。)

你可能感兴趣的:(java,JavaScript,freemarker,ueditor,word,html)