• Java实现word excel ppt模板渲染与导出及预览 LibreOffice jodconverter


    Java Office

    一、文档格式转换

    文档格式转换是office操作中经常需要进行一个操作,例如将docx文档转换成pdf格式。

    java在这方面有许多的操作方式,大致可以分为内部调用(无需要安装额外软件),外部调用(需要安装额外软件)。

    其中,内部调用的方式虽然简单,但是会遇到一些头痛的问题,例如:文档格式错误,字体错误,内容缺少。外部调用虽然麻烦,但可以在一定程度上解决这些问题。

    在技术搭配上比较推荐:jodconverter+LibreOffice

    jodconverter:jodconverter是一种Java OpenDocument转换器,能够转换不同格式的文档,依赖于Apache OpenOffice或 LibreOffice。

    LibreOffice:LibreOffice 是一款功能强大的办公软件,默认使用开放文档格式 (OpenDocument Format , ODF), 并支持 docx, xlsx, pptx 等其他格式。

    jodconverter是支持LibreOfficeApache OpenOffice两种开源的Office软件的,但是从稳定性、转换效果、简单性,更推荐LibreOffice。

    1 LibreOffice安装

    LibreOffice官网:https://www.libreoffice.org/

    LibreOffice下载地址:https://www.libreoffice.org/download/download-libreoffice/

    LibreOffice 7.5.6:https://www.libreoffice.org/donate/dl/win-x86_64/7.5.6/zh-CN/LibreOffice_7.5.6_Win_x86-64.msi

    在这里插入图片描述

    其中,官方一般会发布两个版本,即最新版本和稳定版本,这里推荐稳定版本,根据自己的操作系统的版本下载对应的安装包。

    其中安装流程一直点下一步就好了,记住安装路径就行。

    2 项目maven依赖

    <dependency>
        <groupId>org.jodconvertergroupId>
        <artifactId>jodconverter-localartifactId>
        <version>4.4.6version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3 代码逻辑与实现

    1. 创建OfficeManager
    2. 创建Converter
    3. 创建输入流与输出流
    4. 文档格式转换
    5. 关闭数据流和程序
    3.1 创建OfficeManager
    LocalOfficeManager.Builder builder = LocalOfficeManager.builder();
    // 设置本地Office地址,推荐LibreOffice
    builder.officeHome("D:/Program Files/LibreOffice");
    // 部署主机,本地启动
    builder.hostName("127.0.0.1");
    // 部署端口,可以设置多个
    builder.portNumbers(9000, 9001, 9002);
    // 单任务过期时间 默认:120000 2分钟
    builder.taskExecutionTimeout((long) (5 * 1000 * 60));
    // 任务过期时间 默认:30000 3 秒
    builder.taskQueueTimeout((long) (1000 * 60 * 60));
    // 可以执行的最大任务数,默认200
    builder.maxTasksPerProcess(1000);
    // 构建
    LocalOfficeManager manager = builder.build();
    // 启动
    manager.start();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    3.2 创建Converter
    LocalConverter converter = LocalConverter.builder().officeManager(manager).build();
    
    • 1
    3.3 创建输入流与输出流
    // 测试word文档转pdf
    // 创建输入流
    FileInputStream input = new FileInputStream("E:/tmp/word/test.docx");
    // 创建输出流
    FileOutputStream output = new FileOutputStream("E:/tmp/word/test.pdf");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    3.4 格式转换
    // 进行格式转换
    converter.convert(input).as(DefaultDocumentFormatRegistry.DOCX)
            .to(output).as(DefaultDocumentFormatRegistry.PDF).execute();
    
    • 1
    • 2
    • 3
    3.5 关闭流
    // 关闭流
    output.close();
    input.close();
    manager.stop();
    
    • 1
    • 2
    • 3
    • 4

    4 可支持的文档类型

    public static final @NonNull DocumentFormat PDF = byExtension("pdf");
    public static final @NonNull DocumentFormat SWF = byExtension("swf");
    public static final @NonNull DocumentFormat HTML = byExtension("html");
    public static final @NonNull DocumentFormat XHTML = byExtension("xhtml");
    public static final @NonNull DocumentFormat ODT = byExtension("odt");
    public static final @NonNull DocumentFormat OTT = byExtension("ott");
    public static final @NonNull DocumentFormat FODT = byExtension("fodt");
    public static final @NonNull DocumentFormat SXW = byExtension("sxw");
    public static final @NonNull DocumentFormat DOC = byExtension("doc");
    public static final @NonNull DocumentFormat DOCX = byExtension("docx");
    public static final @NonNull DocumentFormat DOTX = byExtension("dotx");
    public static final @NonNull DocumentFormat RTF = byExtension("rtf");
    public static final @NonNull DocumentFormat WPD = byExtension("wpd");
    public static final @NonNull DocumentFormat TXT = byExtension("txt");
    public static final @NonNull DocumentFormat ODS = byExtension("ods");
    public static final @NonNull DocumentFormat OTS = byExtension("ots");
    public static final @NonNull DocumentFormat FODS = byExtension("fods");
    public static final @NonNull DocumentFormat SXC = byExtension("sxc");
    public static final @NonNull DocumentFormat XLS = byExtension("xls");
    public static final @NonNull DocumentFormat XLSX = byExtension("xlsx");
    public static final @NonNull DocumentFormat XLTX = byExtension("xltx");
    public static final @NonNull DocumentFormat CSV = byExtension("csv");
    public static final @NonNull DocumentFormat TSV = byExtension("tsv");
    public static final @NonNull DocumentFormat ODP = byExtension("odp");
    public static final @NonNull DocumentFormat OTP = byExtension("otp");
    public static final @NonNull DocumentFormat FODP = byExtension("fodp");
    public static final @NonNull DocumentFormat SXI = byExtension("sxi");
    public static final @NonNull DocumentFormat PPT = byExtension("ppt");
    public static final @NonNull DocumentFormat PPTX = byExtension("pptx");
    public static final @NonNull DocumentFormat POTX = byExtension("potx");
    public static final @NonNull DocumentFormat ODG = byExtension("odg");
    public static final @NonNull DocumentFormat OTG = byExtension("otg");
    public static final @NonNull DocumentFormat FODG = byExtension("fodg");
    public static final @NonNull DocumentFormat SVG = byExtension("svg");
    public static final @NonNull DocumentFormat VSD = byExtension("vsd");
    public static final @NonNull DocumentFormat VSDX = byExtension("vsdx");
    public static final @NonNull DocumentFormat PNG = byExtension("png");
    public static final @NonNull DocumentFormat JPEG = byExtension("jpg");
    public static final @NonNull DocumentFormat TIFF = byExtension("tif");
    public static final @NonNull DocumentFormat GIF = byExtension("gif");
    public static final @NonNull DocumentFormat BMP = byExtension("bmp");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    5 完整代码

    public static void main(String[] args) throws OfficeException, IOException {
    
        // =======================构建office管理器========================
        LocalOfficeManager.Builder builder = LocalOfficeManager.builder();
        // 设置本地Office地址,推荐LibreOffice
        builder.officeHome("D:/Program Files/LibreOffice");
        // 部署主机,本地启动
        builder.hostName("127.0.0.1");
        // 部署端口,可以设置多个
        builder.portNumbers(9000, 9001, 9002);
        // 单任务过期时间 默认:120000 2分钟
        builder.taskExecutionTimeout((long) (5 * 1000 * 60));
        // 任务过期时间 默认:30000 3 秒
        builder.taskQueueTimeout((long) (1000 * 60 * 60));
        // 可以执行的最大任务数,默认200
        builder.maxTasksPerProcess(1000);
        // 构建
        LocalOfficeManager manager = builder.build();
        // 启动
        manager.start();
        // ======================构建文档转换器======================
        LocalConverter converter = LocalConverter.builder().officeManager(manager).build();
        // ======================实现文档转换=======================
        // 测试word文档转pdf
        // 创建输入流
        FileInputStream input = new FileInputStream("E:/tmp/word/test.docx");
        // 创建输出流
        FileOutputStream output = new FileOutputStream("E:/tmp/word/test.pdf");
        // 进行格式转换
        converter.convert(input).as(DefaultDocumentFormatRegistry.DOCX)
                .to(output).as(DefaultDocumentFormatRegistry.PDF).execute();
        // 关闭流
        output.close();
        input.close();
        manager.stop();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    效果图

    在这里插入图片描述

    转换后

    在这里插入图片描述

    二、Spring Boot集成模式

    jodconverter有对于Spring Boot的集成解决方案:jodconverter-spring-boot-starter

    1 项目依赖

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starterartifactId>
    dependency>
    
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-testartifactId>
        <scope>testscope>
    dependency>
    <dependency>
        <groupId>org.jodconvertergroupId>
        <artifactId>jodconverter-spring-boot-starterartifactId>
        <version>4.4.6version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2 配置文件

    jodconverter:
      local:
        office-home: D:/Program Files/LibreOffice
        enabled: true
        port-numbers:
          - 8100
          - 8101
          - 8102
          - 8103
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3 测试单例

    @SpringBootTest
    class SpringBootOfficeApplicationTests {
    
        @Resource
        private LocalConverter converter;
        @Test
        void contextLoads() throws IOException, OfficeException {
            // 测试word文档转pdf
            // 创建输入流
            FileInputStream input = new FileInputStream("E:/tmp/word/test.docx");
            // 创建输出流
            FileOutputStream output = new FileOutputStream("E:/tmp/word/test.pdf");
            // 进行格式转换
            converter.convert(input).as(DefaultDocumentFormatRegistry.DOCX)
                    .to(output).as(DefaultDocumentFormatRegistry.PDF).execute();
            output.close();
            input.close();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    三、文档模板渲染输出

    在基于java开发office项目中,需要完成一些文档数据的渲染和输出工作,例如将数据库中的数据渲染到表格中,然后输出pdf。

    目前比较推荐的技术选型是

    首先,刻画模板将模板需要填充部分特殊标记,然后转行为xml格式。

    然后,利用模板引擎将数据与模板进行渲染。

    最后,使用jodconverter转换为pdf输出。

    目前比较推荐的模板引擎是freemarker

    以word文档渲染后输出pdf为例

    1 编写模板文件

    在编写模板中,更推荐使用LibreOffice Writer是安装LibreOffice后自带的客户端。

    在这里插入图片描述

    在保存过程中,记得保存为:fodt格式的文件。

    FODT文件是一种开放文档文本(Flat OpenDocument Text)文件的扩展名。OpenDocument是一种开放的文档标准,旨在提供一种用于创建和编辑文档的自由和开放的文件格式。FODT文件通常包含文本文档的内容,可以包括文字、格式设置、图像和其他与文档相关的元素。这个文件格式的一个常见用途是与LibreOffice和Apache OpenOffice等开源办公套件一起使用。

    在这里插入图片描述

    2 项目设计

    2.1 项目依赖
    
        org.jodconverter
        jodconverter-local
        4.4.6
    
    
        org.freemarker
        freemarker
        2.3.32
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    2.2 核心逻辑

    freemarker工具类

    public class FreemarkerUtils {
    
        public static final Configuration CONFIGURATION;
    
        public static final String TEMPLATE_DIRECTORY = "E:/tmp/word";
    
        static {
            // 初始化
            CONFIGURATION = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
            // 编码
            CONFIGURATION.setDefaultEncoding("UTF-8");
            //模板文件夹路径
            try {
                // CONFIGURATION.setClassForTemplateLoading(FreemarkerUtils.class, path);
                CONFIGURATION.setDirectoryForTemplateLoading(new File(TEMPLATE_DIRECTORY));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    
        public static String rendering(String templateName, Map<String, Object> params) throws IOException, TemplateException {
            Writer writer = new StringWriter();
            Template template = CONFIGURATION.getTemplate(templateName);
            template.process(params, writer);
            writer.close();
            return writer.toString();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    // ======================实现文档转换=======================
    // 测试word文档转pdf
    Map<String, Object> map = new HashMap<>(3);
    map.put("name", "张山");
    map.put("age", 18);
    map.put("text", "性格开朗,热情大方,富有正义感,勤奋好学,对工作认真负责。");
    String dom = FreemarkerUtils.rendering("模板1.fodt", map);
    // 创建输入流
    ByteArrayInputStream input = new ByteArrayInputStream(dom.getBytes());
    // 创建输出流
    FileOutputStream output = new FileOutputStream("E:/tmp/word/模板1.pdf");
    // 进行格式转换
    converter.convert(input).as(DefaultDocumentFormatRegistry.DOCX)
            .to(output).as(DefaultDocumentFormatRegistry.PDF).execute();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    2.3 效果展示

    在这里插入图片描述

    四、实现文档预览

    如果文件格式转换和文档渲染是基于文件操作的话,文档预览是需要引出图片操作了。

    文档预览需要让文档转换为pdf后再转换成图片进行查看。

    实现pdf转换成图片推荐:apache.pdfbox

    1 项目依赖

    <dependency>
        <groupId>org.apache.pdfboxgroupId>
        <artifactId>pdfboxartifactId>
        <version>2.0.27version>
    dependency>
    <dependency>
        <groupId>org.apache.pdfboxgroupId>
        <artifactId>pdfbox-toolsartifactId>
        <version>2.0.27version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2 具体代码

    // 创建字节输出流
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    // 进行格式转换
    converter.convert(input).as(DefaultDocumentFormatRegistry.DOCX)
            .to(output).as(DefaultDocumentFormatRegistry.PDF).execute();
    // 创建文档
    PDDocument document = PDDocument.load(output.toByteArray());
    // 读取文档
    PDFRenderer pdfRenderer = new PDFRenderer(document);
    // 将文档每一张图片存入
    for (int i = 0; i < document.getNumberOfPages(); i++) {
        BufferedImage bufferedImage = pdfRenderer.renderImageWithDPI(i, 600);
        ImageIO.write(bufferedImage, "PNG", new File("E:\\tmp\\word\\" + i + ".png"));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述

  • 相关阅读:
    【Python高级语法】——迭代器 (Iterator)
    五天搞定Mysql基础知识-Day05
    14.7 Socket 循环结构体传输
    美联储会议纪要显示 美联储将继续加息直到通胀大幅缓解
    ebay运营思路|学会这些技巧,新店铺销量翻倍
    8.cookie的获取
    什么是“2 Way SSL”以及它是如何工作的?
    【Android】Android Framework系列---CarPower深度睡眠STR
    稀碎从零算法笔记Day12-LeetCode:找出字符串中第一个匹配项的下标
    qt判断当前日期是不是当月的最后一天
  • 原文地址:https://blog.csdn.net/zhongjianboy/article/details/133338074