preface

Suddenly one day, when OpenOffice converted Word into PDF in the business system, some Chinese characters were lost and the format changed. This is fatal in business systems for previewing important attachments such as contracts. Google could not find the problem for a long time. So use LibreOffice for conversion, see the conversion effect. The principle of online preview of Office files is the same. First convert the files to PDF and then use PDF.js to preview.

Problem of repetition

The original word file

OpenOffice converted PDF file

link

  • For details on how to use OpenOffice, see Section 4 of The Cross-platform (Uni-App) File Online Preview Solution

  • For details on how to use pdF.js, see The Solution for Cross-platform (Uni-app) File Preview online.

  • LibreOffice and OpenOffice Chinese garble problem, the solution is explained later

Quick start

download

address

Download the latest version, currently 7.0.1

Download three packages:

  • Package: Lord LibreOffice_7. 0.1 _Linux_x86-64 _rpm. Tar. Gz
  • The SDK: LibreOffice_7. 0.1 _Linux_x86-64 _rpm_sdk. Tar. Gz
  • Language package: libreoffice_7.0.1_linux_x86-64_RPm_langpack_zh.tar.gz

The installation

  • The main package
cdLibreoffice_7.0.1.2_linux_x86-64_rpm /RPMS yum localinstall -y *.rpmCopy the code
  • SDK
cdLibreoffice_7.0.1.2 _linux_x86-64_rpm_sdk /RPMS yum localinstall -y *.rpmCopy the code
  • Language pack
cdLibreoffice_7.0.1.2 _linux_x86-64_rpm_langpack_zh-cn yum localinstall -y *.rpmCopy the code

Start the

/ opt/libreoffice7.0 / program/soffice - headless - accept ="Socket, host = 127.0.0.1, port = 8101; urp;" --nofirststartwizard > /opt/server/libre.log 2>&1 &
Since the launch of #Add the above command to /etc/rc.localCopy the code

test

Libreoffice7.0 --headless --invisible --convert-to PDF Original Office files --outdir output directoryCopy the code

Java integration

Install the jar

<dependency>
	<groupId>org.jodconverter</groupId>
	<artifactId>jodconverter-local</artifactId>
	<version>4.3.0</version>
</dependency>
Copy the code

Configuration file libre.properties

Create libre.properties under the Resources directory

# LibreOffice home directoryLibreOfficeHome = / opt/libreoffice7.0# Start multiple LibreOffice processes, one for each port
3 # portNumbers = 2002200
portNumbers=8101
Task execution timeout is 5 minutes
taskExecutionTimeoutMinutes=5
The task queue timeout is 1 hour
taskQueueTimeoutHours=1
Copy the code

Read the configuration and connect to the LibreOffice service

New classes: OfficeManagerInstance. Java

package cn.sccl.common.config;

import org.jodconverter.core.office.OfficeManager;
import org.jodconverter.local.office.LocalOfficeManager;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.Properties;

@Component
public class OfficeManagerInstance {
    private static OfficeManager INSTANCE = null;

    public static synchronized void start(a) {
        officeManagerStart();
    }

    @PostConstruct
    private void init(a) {
        try {
            Properties properties = PropertiesLoaderUtils.loadAllProperties("libre.properties");
            String[] portNumbers = properties.getProperty("portNumbers"."").split(",");
            int[] ports = new int[portNumbers.length];

            for (int i = 0; i < portNumbers.length; i++) {
                ports[i] = Integer.parseInt(portNumbers[i]);
            }

            LocalOfficeManager.Builder builder = LocalOfficeManager.builder().install();
            builder.officeHome(properties.getProperty("libreOfficeHome".""));
            builder.portNumbers(ports);
            builder.taskExecutionTimeout(Long.parseLong(properties.getProperty("taskExecutionTimeoutMinutes"."")) * 1000 * 60); // minute
            builder.taskQueueTimeout(Long.parseLong(properties.getProperty("taskQueueTimeoutHours"."")) * 1000 * 60 * 60); // hour

            INSTANCE = builder.build();
            officeManagerStart();
        } catch(IOException e) { e.printStackTrace(); }}private static void officeManagerStart(a) {
        if (INSTANCE.isRunning()) {
            return;
        }

        try {
            INSTANCE.start();
        } catch(Exception e) { e.printStackTrace(); }}}Copy the code

Utility class LibreOfficeUtil

Create a new utility class: libreOfficeutil.java

package cn.sccl.common.util;

import cn.sccl.common.config.OfficeManagerInstance;
import org.jodconverter.local.JodConverter;

import java.io.File;

public class LibreOfficeUtil {
    /** * Use JodConverter to convert Offfice documents to PDF (depending on LibreOffice). This conversion is synchronous and will be completed when you return. */
    public static boolean convertOffice2PDFSyncIsSuccess(File sourceFile, File targetFile) {
        try {
            OfficeManagerInstance.start();
            JodConverter.convert(sourceFile).to(targetFile).execute();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }

    /** * Use LibreOffice to convert Office documents to PDF. The conversion is asynchronous and may still be in progress when the conversion is returned@paramFilePath Target file address *@paramTargetFilePath Output folder *@returnThe return value */ when the child thread completes execution
    public static int convertOffice2PDFAsync(String filePath, String fileName, String targetFilePath) throws Exception {
        String command;
        int exitStatus;
        String osName = System.getProperty("os.name");
        String outDir = targetFilePath.length() > 0 ? " --outdir " + targetFilePath : "";

        if (osName.contains("Windows")) {
            command = "cmd /c cd /d " + filePath + " && start soffice --headless --invisible --convert-to pdf ./" + fileName + outDir;
        } else {
            command = "Libreoffice6.3 -- Headless -- Invisible --convert-to PDF :writer_pdf_Export" + filePath + fileName + outDir;
        }

        exitStatus = executeOSCommand(command);
        return exitStatus;
    }

    / * * * calls to the operating system console, execute the command execution is *, the method does not return until instruction execution is completed, but the return immediately after execution, return the result is 0, only that the correct calls to the operating system console command, but the execution result how, whether there are abnormal, is not reflected here, Therefore, a better posture is to use the synchronous transition function. * /
    private static int executeOSCommand(String command) throws Exception {
        Process process;
        process = Runtime.getRuntime().exec(command); // Conversion takes time, such as 8 seconds for a 3M document, but in actual testing, the next line of code is executed immediately after the command is sent, rather than waiting for the conversion to finish.

        int exitStatus = process.waitFor();

        if (exitStatus == 0) {
            exitStatus = process.exitValue();
        }

        // Destroy the child process
        process.destroy();
        returnexitStatus; }}Copy the code

Method of use

boolean ret = LibreOfficeUtil.convertOffice2PDFSyncIsSuccess(sourceFile, pdfFile);
Copy the code

Effect of contrast

The result is significantly better than OpenOffice, in terms of conversion rate, about the same time, this is not calculated in detail.

Chinese garble problem solved

Whether you use LibreOffice or OpenOffice, you will encounter Chinese garbled characters. The unified solution is as follows:

Environment: CentOS7

  • View the font directoryvim /etc/fonts/fonts.conf/usr/share/fonts/ by default
  • Installing Chinese fonts
mkdir /usr/share/fonts/chinese
cd /usr/share/fonts/chinese
Copy Windows fonts to this directory as follows: Search for "simplified" and copy all
Copy the code

chmod 755 *.TTF
chmod 755 *.TTC
# yum install mkfontscale: command not found
mkfontscale

mkfontdir

# yum install fontconfig fc-cache: command not found
fc-cache -fv

After installation, restart LibreOffice or OpenOffice service
Copy the code

LibreOffice vs OpenOffice is an online preview solution for cross-platform files