springboot jodconverter openoffice 實現 office 文件 在線預覽


這個已是好幾個月前做的,好多細節已記得不那邊清楚了。今天部署到環境還遇到不少問題。總結下。

1、office 文件實現在線預覽的一般思路就是,將文件轉pdf,在通過pdf.js 實現在線瀏覽。這其中轉pdf 各個工具轉換的效果有些差異,存在走樣問題。

2、另一種思路是通過腳本調用office 的轉換pdf功能,這種效果最好,高保真。但就是會麻煩些,依賴office 工具。

3、如果還要部署到Linux上使用哪就只能用開源的辦公軟件 openoffice 了。

4、jodconverter 能很好的調用openoffice 工具轉換 配置也相對比較簡單。

效果圖:

 

 

 

springboot 默認集成了jodconverter 所有應用起來很方便

yml 中加入如下配置就可以了

jodconverter:
enabled: true #注意這個開關,今天部署時就遇到這個問題,排查好久才發現。
officeHome: C:\Program Files (x86)\OpenOffice 4
portNumbers: 8101,8102,8103,8104,8105
maxTasksPerProcess: 5

 

核心代碼:

  public boolean office2pdf(FileEntity fileEntity, String suffix) {
    LOG.info("call office to pdf ,file info:" + fileEntity.toString());
    File file = new File(fileEntity.getAbsolute_path());
    if (file.exists() && file.isFile()) {
      LOG.info("call office to pdf ,find file info:" + fileEntity.toString());
      try {
        File pdfFile = new File(file.getParentFile(), fileEntity.getPrn() + suffix);
        if (!pdfFile.exists()) {
          DocumentConverter documentConverter = szAppConfig.getBeanByClass(DocumentConverter.class);
          documentConverter.convert(file).to(pdfFile).execute();
          if (".html".equalsIgnoreCase(suffix)) {
            try {
              String htmlFormant =
                  "<script src=\"" + sz_ng_root_path + "/commons/js/333614537928.js\"></script>\n" +
                      "    <STYLE>\n" +
                      "        \n" +
                      "        BODY, DIV, TABLE, THEAD, TBODY, TFOOT, TR, TH, TD, P {\n" +
                      "            font-family: \"微軟雅黑\";\n" +
                      "            font-size: x-small\n" +
                      "        }\n" +
                      "\n" +
                      "        TABLE {\n" +
                      "            margin: 0 auto;\n" +
                      "            border-collapse: inherit;\n" +
                      "        }\n" +
                      "\n" +
                      "        .tabBox {\n" +
                      "            border-bottom: 1px solid #ccc;\n" +
                      "            padding-bottom: 1px;\n" +
                      "            height: 30px;\n" +
                      "            line-height: 30px;\n" +
                      "            color: #696969;\n" +
                      "        }\n" +
                      "\n" +
                      "        .tabBox a {\n" +
                      "            float: left;\n" +
                      "            font-family: \"微軟雅黑\";\n" +
                      "            cursor: pointer;\n" +
                      "            padding: 0px 25px 0px;\n" +
                      "            font-size: 13px;\n" +
                      "            height: 30px;\n" +
                      "            line-height: 30px;\n" +
                      "            background: #F4F5F9;\n" +
                      "            border-top: 1px solid #C5D0DC;\n" +
                      "            border-left: 1px solid #C5D0DC;\n" +
                      "            border-bottom: 1px solid #C5D0DC;\n" +
                      "        }\n" +
                      "\n" +
                      "        .tabBox a.current {\n" +
                      "            border-bottom: 0px;\n" +
                      "            border-top: 2px solid #7599DE;\n" +
                      "            font-size: 13px;\n" +
                      "            color: #343434;\n" +
                      "            background: #FFFFFF;\n" +
                      "\n" +
                      "        }\n" +
                      "\n" +
                      "        .tabBox a:last-child {\n" +
                      "            border-right: 1px solid #C5D0DC;\n" +
                      "        }\n" +
                      "\n" +
                      "        .tabDetail {\n" +
                      "            display: none;\n" +
                      "        }\n" +
                      "    </STYLE>\n" +
                      "\n" +
                      "\n" +
                      "<script type=\"text/javascript\">\n" +
                      "    $(function () {\n" +
                      "        var tabs = $(\"[href^='#table']\");\n" +
                      "        $(\"H1:contains('摘要')\").remove();\n" +
                      "        tabs.wrapAll(\"<p class=\\\"tabBox\\\"></p>\");\n" +
                      "        tabs.removeAttr(\"href\");\n" +
                      "        var tabContents = $(\"a[NAME]\");\n" +
                      "        tabContents.each(function () {\n" +
                      "            var tcid = $(this).attr(\"name\");\n" +
                      "            var tc = $(this).next();\n" +
                      "            var tcl = $(this).prev();\n" +
                      "            $(this).wrap(\"<div class=\\\"tabDetail\\\"></div>\")\n" +
                      "            tc.appendTo($(this).parent());\n" +
                      "            tcl.appendTo($(this).parent());\n" +
                      "        });\n" +
                      "    });\n" +
                      "    $(function () {\n" +
                      "        $($('.tabBox > a')[0]).attr(\"class\",\"current\");\n" +
                      "        $($('.tabDetail')[0]).show();\n" +
                      "        $('.tabBox > a').on(\"click\",function(){\n" +
                      "            var num=$(this).index();\n" +
                      "            console.log(num)\n" +
                      "            $('.tabBox > a').each(function(){\n" +
                      "                if($(this).index()==num){\n" +
                      "                    $(this).attr(\"class\",\"current\");\n" +
                      "                    $('.tabDetail').hide();\n" +
                      "                    $($('.tabDetail')[num]).show();\n" +
                      "                }else{\n" +
                      "                    $(this).attr(\"class\",\"\");\n" +
                      "                }\n" +
                      "            });\n" +
                      "        });\n" +
                      "    });\n" +
                      "</script>\n" +
                      "</HTML>";
              RandomAccessFile raf = new RandomAccessFile(pdfFile.getAbsolutePath(), "rw");
              long lastPoint = 0; //記住上一次的偏移量
              String line = null;
              while ((line = raf.readLine()) != null) {
                final long ponit = raf.getFilePointer();
                if (line.toUpperCase().contains("</HTML>")) {
                  String str = line.toUpperCase().replace("</HTML>", htmlFormant);
                  raf.seek(lastPoint);
                  raf.write(str.getBytes("gb2312"));
                }
                lastPoint = ponit;
              }
              raf.close();
            } catch (IOException e) {
              e.printStackTrace();
            }
          }
          LOG.info("call office to pdf ,convert over. file info:" + fileEntity.toString());
        }
        return true;
      } catch (OfficeException e) {
        e.printStackTrace();
        LOG.info(
            "call office to pdf ,thrown error info:" + e.toString() + ", file info:" + fileEntity
                .toString());
        return false;
      }
    }
    return false;
  }

 

上面有一個任意讀寫文件,是為了加入自定已的js 來控制excle 的展示樣式。反正當時糾結了好久。

pom:

<!--open office-->
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-core</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-local</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-spring-boot-starter</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.libreoffice</groupId>
<artifactId>juh</artifactId>
<version>5.4.2</version>
</dependency>
<dependency>
<groupId>org.libreoffice</groupId>
<artifactId>jurt</artifactId>
<version>5.4.2</version>
</dependency>
<dependency>
<groupId>org.libreoffice</groupId>
<artifactId>ridl</artifactId>
<version>5.4.2</version>
</dependency>
<dependency>
<groupId>org.libreoffice</groupId>
<artifactId>unoil</artifactId>
<version>5.4.2</version>
</dependency>
<dependency>
<groupId>org.libreoffice</groupId>
<artifactId>unoloader</artifactId>
<version>5.4.2</version>
</dependency>

代碼就這么些着實有些簡潔,卻實現了一個看着不那么容易的功能。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM