java-springboot中使用freemarker模板生成并doc与pdf文件

转载请注明出处即可:https://blog.csdn.net/qq_35431789/article/details/114258862

接口几乎已经兼容了所有主流的浏览器。

这个功能还是我接手的别人写的未成品基础上写的……顺便吐槽下ftl模板文件是真的麻烦!

使用freemarker模板生成doc与pdf文件。一般使用freemarker模板生成doc与pdf文件的功能是因为系统中有需要固定生成的文档格式需求,本篇基本能解决这类需求。大家可以通过这篇博文进行学习和参考。

模板的上传功能就不写了,因为大家的文件存储方式和位置都不同,只写如何生成doc和pdf的功能。

以下是代码内容:

1、controller:

/**
     * 下载
     *
     * @param
     * @param id 是模板的ID
     * @param snumber 是要定义的文件名称
     * @param type 判断是下载什么模板,这里自定义
     * @param downloadtype 下载的文件类型
     * @throws IOException
     * @return
     * 具体的传参请根据需求修改
     */
    @RequestMapping(value = "download")
    @ResponseBody
    public JSONObject exportToWord(HttpServletResponse response, HttpServletRequest request,
                                   @RequestParam("id") String id,
                                   @RequestParam("snumber") String snumber,
                                   @RequestParam("downloadtype") String downloadtype,
                                   @RequestParam("type") String type) throws Exception {

        //map用来存放需要插入文件的内容
        Map map = new HashMap<>();
        InputStream input = null;
        OutputStream outs = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        
        //这里定义实体list的数据对象,根据自己的需求请灵活使用
        List list = new ArrayList();
        JSONObject jsonobj = new JSONObject();
        //使用临时文件
        File file = File.createTempFile(snumber,".doc");
        log.info("临时文件所在的本地路径:" + file.getCanonicalPath());
        String PDFfileName =null;
        try {
            if(Integer.parseInt((type)) ==0 ){//判断是下载什么模板
                //获取插入模板的数据
                list = server.findAlldataByOrderId(snumber);
            }else if(Integer.parseInt((type)) ==2 ){
                //获取插入模板的数据
                list = server.findAlldataByOrder(snumber);
            }
            if (list == null || list.size() <= 0) {
                jsonobj.put("success", false);
                jsonobj.put("msg", "获取数据失败!");
                return jsonobj;
            }
            ExportContract ext = list.get(0);
            //账户名称
            map.put("sname ", ext.getSname());


            //list遍历表格数据,根据freemarker规范定义,表格内的数据需要单独存放
            List prolist = new ArrayList();

            for (int i = 0; i < list.size(); i++) {
                Map mapdetail = new HashMap();
                ExportContract extdtl = list.get(i);
                //数量
                mapdetail.put("qty", extdtl.getQty());
                prolist.add(mapdetail);
            }

            map.put("prolist", prolist);

            //读取ftl文件
            Configuration conf = new Configuration(new Version("2.3.0"));
            conf.setDefaultEncoding("UTF-8");
            //模板文件的读取方式有三种,请根据使用场景自行查询,这里只写本地存放ftl文件
            conf.setDirectoryForTemplateLoading(new File("/contract_template"));
            Template tem=null;

            //输出文档路径及名称
            String downFileName = null;

            //utf-8读取模板ftl文件
            String filename = server.findByUrls(id);
            //先获取rul,在截取文件名
            String name = filename;
            //Template tem = conf.getTemplate(name, "utf-8");
            try {
                tem = conf.getTemplate(name);
            } catch (Exception e) {
                e.printStackTrace();
            }
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"), 10240);
            tem.process(map, out);
            out.close();
            // 设置强制下载不打开
            if(downloadtype.equals("PDF")){
                //word文档转pdf文档
                PDFfileName = word2Pdf(file.getCanonicalPath(), null);
                log.info("PDF文件临时地址:"+PDFfileName);
                    if(Integer.parseInt((type)) ==0 ){
                        downFileName = ext.getSname() + snumber + ".pdf";
                    }else if(Integer.parseInt((type)) ==2 ){
                        downFileName = ext.getSname() + snumber + ".pdf";
                    }
                bis = new BufferedInputStream(new FileInputStream(PDFfileName));
            }else{
                if(Integer.parseInt((type)) ==0 ){
                    downFileName = ext.getSname() + snumber + ".doc";
                }else if(Integer.parseInt((type)) ==2 ){
                    downFileName = ext.getSname() + snumber + ".doc";
                }
                bis = new BufferedInputStream(new FileInputStream(file));
            }
            response.setCharacterEncoding("UTF-8");
            response.addHeader("Content-Disposition", "attachment;fileName=" + downFileName);
            response.setContentType("application/octet-stream;charset=utf-8");
            final String agent = request.getHeader("User-Agent");
            String attachment = "attachment;fileName=";
            filename = downFileName;
            outs = response.getOutputStream();
            bos = new BufferedOutputStream(outs);
            String outputFilename = null;
            if (agent.indexOf("Firefox") > 0) {
                attachment = "attachment;fileName*=";
                outputFilename = "=?UTF-8?B?"
                        + (new String(Base64.encodeBase64(filename
                        .getBytes("UTF-8")))) + "?=";
            } else {
                if (agent.indexOf("MSIE") != -1) {
                    outputFilename = new String(filename.getBytes("gbk"), "iso8859-1");
                } else {
                    outputFilename = new String(filename.getBytes("UTF-8"), "iso8859-1");
                }
            }
            response.setHeader("Content-Disposition", attachment + outputFilename);
            int bytesRead = 0;
            // 输入流进行先读,然后用输出流去写,下面用的是缓冲输入输出流
            byte[] buffer = new byte[512];
            while ((bytesRead = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, bytesRead);
            }
            bos.flush();

            log.info("文件下载成功!!!!!");
            jsonobj.put("success", true);
            return jsonobj;
        } catch (Exception e) {
            e.printStackTrace();
            log.info("文件下载失败!!!!!");
            jsonobj.put("success", false);
            jsonobj.put("msg", "获取数据失败!");
            return jsonobj;
        } finally {
            if (input != null) input.close();
            if (outs != null) outs.close();
            if (bos !=null) bos.close();
            if (bis !=null) bis.close();
            //下载完成删除临时文件
            boolean flag = false;
            boolean flagPDF = false;
            flag = file.getAbsoluteFile().delete();//这里有点小bug,懒得改了,使用时遇到请自己解决
            File filePDF = new File(PDFfileName);
            flagPDF = filePDF.getAbsoluteFile().delete();
            log.info("临时WORD文件是否删除成功:" + flag);
            log.info("临时PDF文件是否删除成功:" + flagPDF);
        }
    }

 

2、Xml2Word2Pdf转换工具类,这个工具类是我网上找到能很好解决转换问题的。使用的aspose.words包。如果部署到Linux服务器,出现乱码,看看是不是字体库没有安装。遇到了不能正确实现的问题请自行探索。

/**
 * @Content: xml->word->pdf (通过freemarker把通过word生成的xml模板动态添加数据并生成word文档,通过aspose.words把word文档转为pdf文档)
 * @Description: aspose.words需付费购买,目前使用破解版,需要引入freemarker的jar和aspose-words-jdk16-15.8.0.jar
 */
public class Xml2Word2Pdf {

    private static Configuration configuration = null;

    /**
     * 初始化配置并设置默认编码UTF-8
     */
    static {
        configuration = new Configuration();
        configuration.setDefaultEncoding("UTF-8");
    }

    /**
     * @Description: 验证aspose.word组件是否授权:无授权的文件有水印标记
     */
    public static boolean getLicense() {
        boolean result = false;
        try {
            String s = "Aspose.Total for JavaAspose.Words for JavaEnterprise20991231209912318bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=";
            ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes());
            //InputStream inputStream = Xml2Word2Pdf.class.getClassLoader().getResourceAsStream("\\license.xml");
            com.aspose.words.License license = new com.aspose.words.License();
            license.setLicense(inputStream);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

   /**
     * 使用aspose.word把word文档转为pdf文档
     *
     * @param sourceFile word文档绝对路径(如:D:/templates/order.doc)
     * @param destFile   pdf文档绝对路径(如:D:/templates/order.pdf)
     */
    public static String word2Pdf(String sourceFile, String destFile) throws Exception {
        destFile = StringUtils.isEmpty(destFile) ? sourceFile.replace(".doc", ".pdf") : destFile;
        // 验证License 若不验证则转化出的pdf文档会有水印产生
        if (!getLicense()) {
            throw new Exception("生成PDF文档,验证License失败!");
        }
        try {
            File file = new File(destFile);  //新建一个空白pdf文档
            FileOutputStream os = new FileOutputStream(file);
            //解决Linux中文支持问题,注意,如果部署到新服务器,需要copy window下的字体到Linux服务器字体文件夹中。
            String osName = System.getProperties().getProperty("os.name");
            if (osName.equals("Linux")) {
                FontSettings.setFontsFolder("/usr/share/fonts" + File.separator, true);
            }
            Document doc = new Document(sourceFile);//通过sourceFile创建word文档对象
            doc.save(os, SaveFormat.PDF);
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("生成PDF文档失败!");
        }
        return destFile;
    }

}

到此,基本实现了这个功能。

你可能感兴趣的:(java,java,spring,boot,freemarker,doc)