文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

JAVA之利用easypoi将word模板导出为pdf(可带图片)

2023-10-24 09:00

关注

1.介绍easypoi

EasyPoi是一款基于POI的Java快速导出/导入Excel工具。它在POI的基础上进行了封装,提供了更加简洁易用的API,使得生成Excel文件更加容易和高效。

使用EasyPoi可以轻松地生成Excel文件,并支持多种格式,如xlsx、xls、csv等。同时,EasyPoi也支持读取Excel文件,可以方便地获取其中的数据,并进行相应的处理。

EasyPoi具有以下特点:

  1. 简单易用:EasyPoi提供了简洁易用的API,使用起来非常方便。

  2. 支持多种格式:EasyPoi支持多种格式的Excel文件,如xlsx、xls、csv等。

  3. 灵活性高:EasyPoi支持多种数据格式,包括文本、数字、日期等,同时也支持复杂数据结构,如嵌套表格等。

  4. 导入导出高效:EasyPoi在性能上进行了优化,导入导出速度快,使用起来非常高效。

总之,EasyPoi是一个非常实用的Java导入导出Excel工具,它可以帮助开发者轻松地生成和处理Excel文件。

easypoi网站:悟耘科技 - Powered by MinDoc

2.改善的word工具类

在百度上面搜索了很多类似的文章,因为自己的业务需求,然后将其他博主的工具类进行了完善,最后还会说一些我做这个工具类 遇到的一些坑,

2.1导入相关依赖

如果是需要 jar包的话可以在下面给我留言

                    cn.afterturn            easypoi-base            4.3.0                            cn.afterturn            easypoi-web            4.3.0                            cn.afterturn            easypoi-annotation            4.3.0                                    org.docx4j            docx4j-export-fo            6.1.0                                                            org.slf4j                    slf4j-log4j12                                    

2.2准备好word模板放在resources项目下

我自己放在这个目录下,因为项目打包的原因,规范一点

2.3word模板样式

里面包含了最简单的一些参数注入

如果需要打印遍历集合,模板可以参考其他博主:java使用easypoi导出word文档,包含图片,表格,文字;_easypoi导出word list图片_一点博客的博客-CSDN博客

 大概是这个样子,比较简单(其他 博主 的 模板)

模板指令:

2.4.工具类 

这个工具类可以直接拿去用,我把这个工具 类封装成一个bean,需要调用的时候在业务层注入 

import cn.afterturn.easypoi.word.WordExportUtil;import org.apache.poi.xwpf.usermodel.XWPFDocument;import org.docx4j.Docx4J;import org.docx4j.convert.out.FOSettings;import org.docx4j.fonts.IdentityPlusMapper;import org.docx4j.fonts.Mapper;import org.docx4j.fonts.PhysicalFonts;import org.docx4j.openpackaging.packages.WordprocessingMLPackage;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.core.io.ResourceLoader;import org.springframework.stereotype.Component;import org.springframework.util.Assert;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.*;import java.net.URLEncoder;import java.nio.charset.StandardCharsets;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Map;@Componentpublic class WordUtil {    @Value(value = "${jeecg.path.upload}")    private String uploadpath;  //从yml文件读取文件下载路径      @Autowired    private  ResourceLoader resourceLoader;    public String exportPdf(WordTemplateEnum templateType, Map params) throws IOException {        String temPath = templateType.getPath();        String absolutePath = resourceLoader.getResource("classpath:" + temPath).getFile().getAbsolutePath();        //String absolutePath = ResourceUtils.getFile("classpath:static\\template\\1.docx").getAbsolutePath();        return exportPdf(absolutePath,params);    }        public  String exportPdf(String templatePath, Map params) {        // 生成的wold文档文件名        String woldFileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".docx";        //保存的文件路径名        String saveDir = uploadpath + File.separator + "pdf";        // 生成的pdf文件名        String pdfFileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".pdf";        // 导出wold文档 返回值为生成的wold文档全路径        String word = exportWord(templatePath, saveDir, woldFileName, params);        cn.hutool.core.lang.Assert.notNull(word, "word路径不能为空");        // 自定义生成的pdf全路径        String pdfPath = saveDir + File.separator + pdfFileName;        // 导出pdf,同时删除生成的wold文档        convertDocx2Pdf(word, pdfPath);        return pdfPath;    }        public String exportWord(String templatePath, String saveDir, String fileName, Map params) {        Assert.notNull(templatePath, "模板路径不能为空");        Assert.notNull(saveDir, "临时文件路径不能为空");        Assert.notNull(fileName, "导出文件名不能为空");        Assert.isTrue(fileName.endsWith(".docx"), "word导出请使用docx格式");        if (!saveDir.endsWith("/")) {            saveDir = saveDir + File.separator;        }        File dir = new File(saveDir);        if (!dir.exists()) {            dir.mkdirs();        }        String savePath = saveDir + fileName;        try {            XWPFDocument doc = WordExportUtil.exportWord07(templatePath, params);            FileOutputStream fos = new FileOutputStream(savePath);            doc.write(fos);            fos.flush();            fos.close();        } catch (Exception e) {            e.printStackTrace();        }        return savePath;    }    public String exportWord(String templatePath, String temDir, String fileName, Map params, HttpServletRequest request, HttpServletResponse response) {        Assert.notNull(templatePath,"模板路径不能为空");        Assert.notNull(temDir,"临时文件路径不能为空");        Assert.notNull(fileName,"导出文件名不能为空");        Assert.isTrue(fileName.endsWith(".docx"),"word导出请使用docx格式");        if (!temDir.endsWith("/")){            temDir = temDir + File.separator;        }        File dir = new File(temDir);        if (!dir.exists()) {            dir.mkdirs();        }        try {            String userAgent = request.getHeader("user-agent").toLowerCase();            if (userAgent.contains("msie") || userAgent.contains("like gecko")) {                fileName = URLEncoder.encode(fileName, "UTF-8");            } else {                fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);            }            XWPFDocument doc = WordExportUtil.exportWord07(templatePath, params);            String tmpPath = temDir + fileName;            FileOutputStream fos = new FileOutputStream(tmpPath);            doc.write(fos);            // 设置强制下载不打开            response.setContentType("application/force-download");            // 设置文件名            response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);            OutputStream out = response.getOutputStream();            doc.write(out);            out.close();        } catch (Exception e) {            e.printStackTrace();        } finally {            //这一步看具体需求,要不要删            //delFileWord(temDir,fileName);        }        return temDir + fileName;    }        public void delFileWord(String filePath, String fileName) {        File file = new File(filePath + fileName);        File file1 = new File(filePath);        file.delete();        file1.delete();    }        public void convertDocx2Pdf(String wordPath, String pdfPath) {        OutputStream os = null;        InputStream is = null;        if (pdfPath.endsWith("/")) {            pdfPath = pdfPath + File.separator;        }        try {            is = new FileInputStream(new File(wordPath));            WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(is);            Mapper fontMapper = new IdentityPlusMapper();            fontMapper.put("隶书", PhysicalFonts.get("LiSu"));            fontMapper.put("宋体", PhysicalFonts.get("SimSun"));            fontMapper.put("微软雅黑", PhysicalFonts.get("Microsoft Yahei"));            fontMapper.put("黑体", PhysicalFonts.get("SimHei"));            fontMapper.put("楷体", PhysicalFonts.get("KaiTi"));            fontMapper.put("新宋体", PhysicalFonts.get("NSimSun"));            fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));            fontMapper.put("华文仿宋", PhysicalFonts.get("STFangsong"));            fontMapper.put("宋体扩展", PhysicalFonts.get("simsun-extB"));            fontMapper.put("仿宋", PhysicalFonts.get("FangSong"));            fontMapper.put("仿宋_GB2312", PhysicalFonts.get("FangSong_GB2312"));            fontMapper.put("幼圆", PhysicalFonts.get("YouYuan"));            fontMapper.put("华文宋体", PhysicalFonts.get("STSong"));            fontMapper.put("华文中宋", PhysicalFonts.get("STZhongsong"));            mlPackage.setFontMapper(fontMapper);            os = new java.io.FileOutputStream(pdfPath);            //docx4j  docx转pdf            FOSettings foSettings = Docx4J.createFOSettings();            foSettings.setWmlPackage(mlPackage);            Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);            is.close();//关闭输入流            os.close();//关闭输出流        } catch (Exception e) {            e.printStackTrace();            try {                if (is != null) {                    is.close();                }                if (os != null) {                    os.close();                }            } catch (Exception ex) {                ex.printStackTrace();            }        } finally {            // 删除word文档的地址            File file = new File(wordPath);            if (file != null && file.isFile() && file.exists()) {                file.delete();            }        }    }        public byte[] getImageBase64(String path) throws IOException {        InputStream input = new FileInputStream(path);        ByteArrayOutputStream output = new ByteArrayOutputStream();        byte[] buf = new byte[1024];        int numBytesRead = 0;        while ((numBytesRead = input.read(buf)) != -1) {            output.write(buf, 0, numBytesRead);        }        byte[] data = output.toByteArray();        output.close();        input.close();        return data;    }}

 其中exportpdf方法调用,第一个参数是模板路径,第二参数是 注入的参数,返回是导出的pdf模板完全路径(业务 需求)

5调用工具类

我就简单的在测试类中写一下,肯定是没有问题的,

import cn.afterturn.easypoi.entity.ImageEntity;@Autowired    private WordUtil wordUtil;    @Test    public void testPostDoctor() throws IOException {        Map params = new HashMap<>();        params.put("enterpriseName","张三");        params.put("contactsName","李四");        params.put("contactsPhone","12345678");        ImageEntity image = new ImageEntity();        image.setHeight(50);        image.setWidth(50);        image.setUrl("https://lmg.jj20.com/up/allimg/4k/s/02/2109250006343S5-0-lp.jpg");        params.put("testCode", image);        String exportPdf = wordUtil.exportPdf("static\\template\\1.docx", params);        System.out.println("exportPdf = " + exportPdf);    }

下面的在application.yml文件写的文件下载路径

jeecg :  path :    #文件上传根目录 设置    upload: D://opt//upFiles

这个根据自己的需求来写,因为我考虑 到项目打包发服务器的,我想想应该没有其他的了把

3.1坑

自己遇到了很多坑在导出模板的,我是先将 wold模板导为wold文件,然后在将wold文件转为pdf

第一个坑:因为自己的模板放在resources目录下面,项目完整启动会将模板加载进target目录里面,会 默认的对docx文件进行压缩,一压缩就乱码, 我找了半个小时才找出问题

大概是这个样子,我们需要在pom.xml文件指明不压缩docx文件

                                   org.apache.maven.plugins                maven-resources-plugin                                                            woff                        woff2                        eot                        ttf                        svg                        docx                                                

这样就不会压缩一些 文件

第二个坑:

当一些属性你没有在map找到的时候,运行 会报空指针

 解决方案:

在map中写满,如果没有值,可以写空字符串都可以,不能不写,

还有一种方案,将工具类底层调用的poiUtil中重写,运行的时候就会先调用 重写的这个类

 然后将代码的这部分修改

 private static Boolean isTrue(String[] keys, Map map) throws Exception {        if (keys.length == 1) {            String constant = null;            if ((constant = isConstant(keys[0])) != null) {                return Boolean.valueOf(constant);            }            Object paramsValue = PoiPublicUtil.getParamsValue(keys[0], map);            if (Objects.isNull(paramsValue)){                return false;            }            return Boolean.valueOf(paramsValue.toString());        }        if (keys.length == 3) {            Object first  = evalNoParse(keys[0], map);            Object second = evalNoParse(keys[2], map);            return PoiFunctionUtil.isTrue(first, keys[1], second);        }        throw new ExcelExportException("判断参数不对");    }

这样即使忘记在map中写了,也不会报错

目前就这些问题了,什么时候遇到新问题了在补充一下,有什么不懂的,或者有问题的可以留言

明天周末,周末愉快!!!!

来源地址:https://blog.csdn.net/xuanzihhh/article/details/132497575

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯