Convert documents to PDF online, Vue2 receives PDF file stream preview

Requirements

The document online preview function is similar to plug-ins such as vue-office-docx. Since the doc format is incompatible, the experience is not good. The next best thing is to convert all documents (doc, ppt, xls, etc.) to PDF online. It is then received and displayed by the front end.

Solution

Use the liberoffice command line to convert documents such as doc into pdf files and save them as temporary files. The vue front-end receives the pdf file stream and uses the vue-office-pdf plug-in to complete the preview.

An easier method is provided at the end of the article~

Backstage

pom

<dependency>
   <groupId>org.apache.commons</groupId>
   <artifactId>commons-exec</artifactId>
   <version>1.3</version>
</dependency>

controller

/**
 * Convert to pdf download
 * @param ossId
 * @param response
 * @throwsIOException
 */
@GetMapping("/downloadPdf/{ossId}")
public void downloadPdf(@PathVariable Long ossId, HttpServletResponse response) throws IOException {
    iSysOssService.downloadToPdf(ossId,response);
}

service

import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteException;
import org.apache.commons.exec.ExecuteResultHandler;
import org.apache.xmlbeans.impl.common.IOUtil;
import java.util.concurrent.Semaphore;

/**
 * Convert to pdf download
 * @param ossId
 * @param response
 * @throwsIOException
 */
public void downloadToPdf(Long ossId, HttpServletResponse response) throws IOException {
    SysOssVo sysOss = SpringUtils.getAopProxy(this).getById(ossId);
    if (ObjectUtil.isNull(sysOss)) {
        throw new ServiceException("File data does not exist!");
    }
    String pdfName = sysOss.getOriginalName().substring(0, sysOss.getOriginalName().indexOf(".")) + ".pdf";

    FileUtils.setAttachmentResponseHeader(response, pdfName);
    response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8");
    try {

        DefaultExecutor exec = new DefaultExecutor();
        File tempFolder = new File(System.getProperty("java.io.tmpdir"), "office2pdf-" + IdUtil.fastSimpleUUID());
        if (!tempFolder.exists()) {
            tempFolder.mkdirs();
        }
        String orginName = tempFolder.getAbsolutePath() + File.separator + sysOss.getOriginalName();
        //Copy local
        OssClient storage = OssFactory.instance();
        try(InputStream inputStream = storage.getObjectContent(sysOss.getUrl())) {
            int available = inputStream.available();
            OutputStream fileOutputStream = new FileOutputStream(orginName);
            IoUtil.copy(inputStream, fileOutputStream, available);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
        // Wait synchronously
        Semaphore semaphore = new Semaphore(1);
        semaphore.acquire();
        ExecuteResultHandler erh = new ExecuteResultHandler() {
            @Override
            public void onProcessComplete(int i) {
                semaphore.release();
                //Conversion completion logic
            }
            @Override
            public void onProcessFailed(ExecuteException e) {
                semaphore.release();
            }
        };
        String command = "soffice --invisible --convert-to pdf --outdir "" + tempFolder.getAbsolutePath() + "" ""
             + orginName + """;
        exec.execute(CommandLine.parse(command), erh);
        // Wait for execution to complete
        semaphore.acquire();

        //response download
        File file = new File(tempFolder.getAbsolutePath() + File.separator + pdfName);
        FileInputStream inputStream = new FileInputStream(file);
        int available = inputStream.available();
        IoUtil.copy(inputStream, response.getOutputStream(), available);
        response.setContentLength(available);
    } catch (Exception e) {
        throw new ServiceException(e.getMessage());
    }
}

Front desk

//pdf document preview component

npm install @vue-office/pdf

<template>
    <!-- pdf direct preview -->
      <div>
        <vue-office-pdf
          :src="pdfUrl"
          @rendered="renderedHandler"
          @error="errorHandler"
        />
      </div>
</template>
//Introducing the VueOfficePdf component
import VueOfficePdf from '@vue-office/pdf'

export default {
  components:{
    VueOfficePdf,
  },
  data() {
    return {
      pdfUrl: "",
      fullscreenLoading: false,
    }
  },
  methods: {
    /** pdf */
    renderedHandler() {
      console.log("Rendering completed")
      this.fullscreenLoading = false
    },
    errorHandler() {
      console.log("Rendering failed")
      this.fullscreenLoading = false
    },
    /** Convert to PDF online */
    ossPdf(ossId) {

      this.fullscreenLoading = true
      var url = process.env.VUE_APP_BASE_API + '/file/downloadPdf/' + ossId
      axios({
        method: 'get',
        url: url,
        responseType: 'blob',
        headers: { 'Authorization': 'Bearer ' + getToken() }
      }).then((res) => {
        const isBlob = blobValidate(res.data);
        if (isBlob) {

          let fileURL = null
          var blob = new Blob([res.data], {type: 'application/pdf'})
          if (window.createObjectURL != undefined) { // basic
            fileURL = window.createObjectURL(blob);
          }else if (window.webkitURL != undefined) { // webkit or chrome
            try {
              fileURL = window.webkitURL.createObjectURL(blob);
            } catch (error) {console.log(error)}
          } else if (window.URL != undefined) { // mozilla(firefox)
            try {
              fileURL = window.URL.createObjectURL(blob);
            } catch (error) {console.log(error)}
          }
          console.log("PDF file address 0 ", fileURL)
          this.pdfUrl = fileURL

        } else {
          this.printErrMsg(res.data);
        }
      }).catch((r) => {
        console.error(r)
        Message.error('An error occurred while downloading the file, please contact the administrator!')
      })
    },
}

Extension

kkFileView-file document online preview

This project is built using the popular spring boot, which is easy to get started and deploy. It basically supports online preview of mainstream office documents, such as doc, docx, xls, xlsx, ppt, pptx, pdf, txt, zip, rar, pictures, videos, audio, etc. wait

docker install and run

When you need to preview a file, you only need to call the browser to open the preview interface of this project and pass in the URL of the file to be previewed.

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Java Skill TreeHomepageOverview 139,100 people are learning the system