SpringBoot使用OpenOffice将word转成pdf

安装

参考这篇文章:Linux环境下安装OpenOffice 4.1.8

引用依赖

  • 这边 jodconverter 用的是 2.2.2 版本,Maven库没有,需要自己去网上下载
  • 我这边是引用本地JAR,这是因为产生了大量WARN日志(找不到JAR包之类的)。虽然不影响使用,但是看着不舒服,所以把相关JAR放到同一个目录下引用了。
        <!--jodconverter 开始 -->
        <dependency>
            <groupId>com.artofsolving</groupId>
            <artifactId>jodconverter</artifactId>
            <version>2.2.2</version>
            <scope>system</scope>
            <systemPath>${
    
    project.basedir}/src/main/resources/lib/jodconverter/jodconverter-2.2.2.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>org.libreoffice</groupId>
            <artifactId>unoloader</artifactId>
            <version>5.1.4</version>
            <scope>system</scope>
            <systemPath>${
    
    project.basedir}/src/main/resources/lib/jodconverter/unoloader.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>org.openoffice</groupId>
            <artifactId>juh</artifactId>
            <version>3.0.1</version>
            <scope>system</scope>
            <systemPath>${
    
    project.basedir}/src/main/resources/lib/jodconverter/juh.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>org.openoffice</groupId>
            <artifactId>jurt</artifactId>
            <version>3.0.1</version>
            <scope>system</scope>
            <systemPath>${
    
    project.basedir}/src/main/resources/lib/jodconverter/jurt.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>org.openoffice</groupId>
            <artifactId>ridl</artifactId>
            <version>3.0.1</version>
            <scope>system</scope>
            <systemPath>${
    
    project.basedir}/src/main/resources/lib/jodconverter/ridl.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>org.openoffice</groupId>
            <artifactId>unoil</artifactId>
            <version>3.0.1</version>
            <scope>system</scope>
            <systemPath>${
    
    project.basedir}/src/main/resources/lib/jodconverter/unoil.jar</systemPath>
        </dependency>
        <!--jodconverter 结束 -->

创建操作类 OfficeToPdf

  • serverUrl: OpenOffice安装的地址,我这边是 192.168.25.131
  • port: OpenOffice服务的端口,默认是 8100
  • 下面这个类,稍微改一改,基本上可以直接使用,这里不演示了
@Component
@Slf4j
public class OfficeToPdf {
    
    
    private OpenOfficeConnection connection;  //OpenOffice连接
    private DocumentConverter converter;      //文件转换器

    @Value("${openoffice.server.url}")
    private String serverUrl;
    @Value("${openoffice.server.port}")
    private Integer port;

    @PostConstruct
    private void init(){
    
    
        //连接OpenOffice
        connection = new SocketOpenOfficeConnection(serverUrl, port);
        checkConnected();
    }

    private void checkConnected(){
    
    
        if (connection.isConnected()){
    
    
            return;
        }
        try {
    
    
            connection.connect();
            converter =  new StreamOpenOfficeDocumentConverter(connection);
        } catch (ConnectException e) {
    
    
            e.printStackTrace();
            log.error(String.format("OpenOffice连接失败,请检查服务是否安装并启动:%s:%s", serverUrl, port));
        }
    }

    public File convert(File file) throws IOException {
    
    
        //判断源文件是否存在
        if (!file.exists()){
    
    
            throw new RuntimeException("源文件不存在!");
        }

        //输出文件
        File outputFile = new File("d:\\1.pdf");

        checkConnected();

        //开始转换
        converter.convert(file, outputFile);

        if (outputFile.exists()){
    
    
            log.info(file.getName()+"文件转换成功");
        }else {
    
    
            log.info(file.getName()+"文件转换失败");
        }

        return outputFile;
    }
}

注意事项

  • 2.2.2 版本的 jodconverter 可以直接转换 docx,其他版本需要创建 DefaultDocumentFormatRegistry 对象,并往里面添加docx类型
  • 每个Connection在同一时刻只能导出一个文件,底层代码加锁了。需要并发就每次调用创建新的Connection。
  • word 格式尽量简单,常规的文字、表格都没问题。在同一页插入多个分节符,可能导致PDF排版错乱。

遇到的问题

我这边代码连接OpenOffice的时候,速度很慢,至少花了10几秒才能连上。如果每次导出都连接一次,那这速度肯定接受不了。

临时的解决方案就是,程序启动的时候,异步开启10个连接(类似连接池),需要导出的时候直接获取连接对象即可。

如果有人知道连接慢的原因,望不吝赐教~~~~

猜你喜欢

转载自blog.csdn.net/qq_28834355/article/details/113238561