This is the 15th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Preview is now a very common power supply. The project manager brought up the need to implement the changes at the meeting. First, the blogger decided on an idea: other documents were converted into PDFS and then streamed to the foreground. Because the front desk supports PDF, you can preview directly. No sooner said than done. So here’s the code.

1. Solution 1: Use the jodconverter-spring-boot-starter method

After some research, I found that Spring provides a JAR package for Jodconverter-Spring-boot-starter. Can complete this function. We just need to follow his API implementation.

1. Modify the POM file

<! -- JodConverter Core Package --><dependency>
            <groupId>org.jodconverter</groupId>
            <artifactId>jodconverter-core</artifactId>
            <version>4.2.2</version>
        </dependency><! -- SpringBoot support package, which includes automatic configuration classes --><dependency>
            <groupId>org.jodconverter</groupId>
            <artifactId>jodconverter-spring-boot-starter</artifactId>
            <version>4.2.2</version>
        </dependency><! -- JodConverter Native Support Pack --><dependency>
            <groupId>org.jodconverter</groupId>
            <artifactId>jodconverter-local</artifactId>
            <version>4.2.2</version>
        </dependency>

Copy the code

2. Modify application. XML

jodconverter:
  local:
    enabled: true
    max-tasks-per-process: 10
    port-numbers: 8100
Copy the code

3. Invoke methods

@RestController
public class OnlinePreviewController {

    // Step 1: the converter is injected directly
    @Autowired
    DocumentConverter documentConverter;

    @GetMapping("/toPdfFile")
    public String toPdfFile(FileMessage fileMessage) {
        / / get the HttpServletResponse
        HttpServletResponse response =
            ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();
        // The file to be converted
        File file = new File(fileMessage.getFileDownloadUri());
        try {
            // The address generated by the file after the conversion
            File newFile = new File("D:/common_files/pdf");
            if(! newFile.exists()) { newFile.mkdirs(); }String converterPdf = "D:/common_files/pdf" + "/" + fileMessage.getFileName() + "-pdf.pdf";
            // File conversion
            documentConverter.convert(file).to(new File(converterPdf)).execute();
            // Use response to stream the first part of the PDF file
            ServletOutputStream outputStream = response.getOutputStream();
            // Read the file
            InputStream in = new FileInputStream(new File(converterPdf));
            / / copy files
            int i = IOUtils.copy(in, outputStream);
            System.out.println(i);
            in.close();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "This is to pdf"; }}Copy the code

However, this can happen when excle overruns, abandon…

2. Solution 2: Use com. artofSolving package

After a little more research, com.artofSolving could do the same.

1. Modify the POM file


       <dependency>
            <groupId>com.artofsolving</groupId>
            <artifactId>jodconverter</artifactId>
            <version>2.2.2</version>
        </dependency>

        <dependency>
            <groupId>org.openoffice</groupId>
            <artifactId>jurt</artifactId>
            <version>3.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.openoffice</groupId>
            <artifactId>ridl</artifactId>
            <version>3.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.openoffice</groupId>
            <artifactId>juh</artifactId>
            <version>3.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.openoffice</groupId>
            <artifactId>unoil</artifactId>
            <version>3.0.1</version>
        </dependency>
Copy the code

Note that 2.2.2 does not have m on maven server, so you need to download it separately and directly access the web disk address.

Link: pan.baidu.com/s/1d5oe7OIa… Extraction code: TOUy

2. The Controller class

import com.artofsolving.jodconverter.DocumentConverter;
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import org.apache.commons.io.IOUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

@RestController
public class OnlinePreviewController {

    @GetMapping("/toPdfFile")
    public void toPdfFile(FileMessage fileMessage) throws IOException {
        / / get the HttpServletResponse
        HttpServletResponse response =
            ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();
        // Source file directory
        File inputFile = new File(fileMessage.getFileDownloadUri());
        if(! inputFile.exists()) { System.out.println("Source file does not exist!");
            return;
        }
        // The address generated by the file after the conversion
        File newFile = new File("D:/common_files/pdf");
        if(! newFile.exists()) { newFile.mkdirs(); }String converterPdf = "D:/common_files/pdf" + "/" + fileMessage.getFileName() + "-pdf.pdf";
        // Output file directory
        File outputFile = new File(converterPdf);
        if(! outputFile.getParentFile().exists()) { outputFile.getParentFile().exists(); }// Call the OpenOffice service thread
        String command =
            "C:/Program Files (x86)/OpenOffice 4/ Program /soffice. Exe -headless-accept =\"socket,host=127.0.0.1,port=8100; urp; \ "";
        Process p = Runtime.getRuntime().exec(command);
        // Connect to the OpenOffice service
        OpenOfficeConnection connection = new SocketOpenOfficeConnection("127.0.0.1".8100);
        connection.connect();
        / / conversion
        DocumentConverter converter = new ConverterDocument(connection);
        converter.convert(inputFile, outputFile);
        ServletOutputStream outputStream = response.getOutputStream();
        // Read the file
        InputStream in = new FileInputStream(new File(converterPdf));
        / / copy files
        int i = IOUtils.copy(in, outputStream);
        in.close();
        outputStream.close();
        // Close the connection
        connection.disconnect();
        // Close the process
        p.destroy();
        System.out.println("Conversion complete!"); }}Copy the code

The conversion method is as follows:

DocumentConverter converter = new ConverterDocument(connection);
        converter.convert(inputFile, outputFile);
Copy the code

Because of the excel line folding problem we changed the paper and rewrote the Conversion document.

3.ConverterDocument

import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.converter.StreamOpenOfficeDocumentConverter;
import com.sun.star.awt.Size;
import com.sun.star.beans.PropertyValue;
import com.sun.star.lang.XComponent;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.view.PaperFormat;
import com.sun.star.view.XPrintable;

public class ConverterDocument extends StreamOpenOfficeDocumentConverter {

    public ConverterDocument(OpenOfficeConnection connection) {
        super(connection);
    }

    public final static Size A5, A4, A3;
    public final static Size B4, B5, B6;
    public final static Size paperSize;
    static {
        A5 = new Size(14800.21000);
        A4 = new Size(21000.29700);
        A3 = new Size(29700.42000);
        B4 = new Size(25000.35300);
        B5 = new Size(17600.25000);
        B6 = new Size(12500.17600);
        // Maximum width 1600000
        paperSize = new Size(29700.27940);
    }

    @Override
    protected void refreshDocument(XComponent document) {
        super.refreshDocument(document);
        XPrintable xPrintable = (XPrintable)UnoRuntime.queryInterface(XPrintable.class, document);
        PropertyValue[] printerDesc = new PropertyValue[2];
        / / conversion
        printerDesc[0] = new PropertyValue();
        printerDesc[0].Name = "PaperFormat";
        printerDesc[0].Value = PaperFormat.USER;
        // Paper size
        printerDesc[1] = new PropertyValue();
        printerDesc[1].Name = "PaperSize";
        printerDesc[1].Value = paperSize;
        try {
            xPrintable.setPrinter(printerDesc);
        } catch(Exception e) { e.printStackTrace(); }}}Copy the code

But there is a problem here, multiple sheets, only the first page has been changed, so there are two solutions.

  1. Combine sheets into a single sheet.
  2. Print multiple sheets separately, too.

However, I found kkFileView open source project emMMMMmmm by chance. It smells good.