使用pdf.js在線預覽 PDF (本地文件,服務器文件)


前言

不使用插件直接進行pdf預覽時,對於小文件沒有任何問題,但在預覽一個305M,近400頁的pdf文件時,打開pdf直接拉到最后幾頁,會造成瀏覽器崩潰,於是嘗試使用pdf.js的插件方式進行pdf預覽,解決大文件瀏覽器崩潰的問題。

1、下載地址

http://mozilla.github.io/pdf.js/

主要用到里邊的 viewer.js 和 viewer.html 文件

 

 

 2、打開文件夾,把這兩個文件放進程序,一個是 build,一個是 web 文件夾,建議整個文件夾都放進去!到這差不多安裝過程就 ok 了,viewer.html 文件里邊有默認的 PDF 文件

 

 

 

 

測試方法 window.open(' ../pdf/web/viewer.html')

3、找到剛剛放入程序的文件,打開 web 文件目錄,打開 viewer.js 文件找到他默認展示的 PDF 文件的路徑改為 value:’’ ( 也可以不修改 ) 

 

 

4、想要調用這個 JS 來預覽 PDF ,方法跟上方測試方法差不多,只不過多加了一個條件
  調用方法:windows.open("/pdf/web/viewer.html?file=file.pdf");
  這個方法只能讀取你 web 目錄下的文件,如果想要讀取你本地文件或者服務器文件 就 通過流的方式輸出


5、獲取本地/服務器文件

前端寫法:通過點擊事件觸發預覽

previewURL: 項目地址路徑
filePath: 要打開的項目
encodeURIComponent:用於 url 特殊字符的轉譯(比如 : ; / ? : @ & = + $ , # 這些用於分隔 URI 組件的標點符號)

// 點擊調用預覽方法
function xx(filePath){
var previewURL= "127.0.0.1:8080/";
window.open('../pdf/web/viewer.html?file='+encodeURIComponent(previewURL+"/test?url="+filePath));
}
后端寫法:拿到文件地址,通過流的方式輸出到移動端頁面顯示

// 通過文件流的方式預覽 PDF 文件
@RequestMapping(value = "test")
public void pdfStreamHandeler(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
// 獲取路徑
String filePath = request.getParameter("url");
File file = new File(filePath);
byte[] data = null;
try {
// 編輯請求頭部信息
// 解決請求頭跨域問題(IE兼容性 也可使用該方法)
response.setHeader("Access-Control-Allow-Origin", "*");
response.setContentType("application/pdf");
FileInputStream input = new FileInputStream(file);
data = new byte[input.available()];
input.read(data);
response.getOutputStream().write(data);
input.close();
} catch (Exception e) {
}
}

下面是我的項目中的調用方式:

/**
* 預覽PDF
*/
@RequiresPermissions("dagl:pdf")
@Log(title = "PDF預覽", businessType = BusinessType.DELETE)
@GetMapping("/pdfPreview/{dh}")
public String pdfPreview(@PathVariable("dh") String dh, ModelMap mmap)
{
mmap.put("pdf_url", fileReadUrl+dazlxxb.getPdfUrl());
return prefix + "/pdfPreview";
}
<!DOCTYPE html>
<html style="height: 100%" lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
    <link th:href="@{/css/update.css}" rel="stylesheet"/>
    <th:block th:include="include :: header('PDF預覽')"/>
    <th:block th:include="include :: datetimepicker-css"/>
</head>
<body class="white-bg">
<iframe  style="width: 100%;height: 100%;" frameborder="0" id="pdfView"></iframe>
</body>
<script th:src="@{/js/jquery.min.js}"></script>
<script th:inline="javascript">
    var pdf_url = [[${pdf_url}]]; var prefix = "/dagl"; $('#pdfView').attr('src', '/pdf/web/viewer.html?file=' + encodeURIComponent(prefix +"/pdfStreamHandeler?pdf_url=" + pdf_url)); </script> </html>
// 通過文件流的方式預覽 PDF 文件
    @RequestMapping(value = "pdfStreamHandeler")
    public void pdfStreamHandeler(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
        // 獲取路徑
        String filePath = request.getParameter("pdf_url");
        try {
            if(StringUtils.isNotBlank(filePath)) {
                byte[] data = fileDfsUtil.downLoadFile(filePath);
                // 編輯請求頭部信息
                // 解決請求頭跨域問題(IE兼容性 也可使用該方法)
                response.setHeader("Access-Control-Allow-Origin", "*");
                response.setContentType("application/pdf");
                response.getOutputStream().write(data);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

 @Component
public class FileDfsUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(FileDfsUtil.class);
    @Resource
    private FastFileStorageClient storageClient ;
    /**
     * 上傳文件
     */
    public String upload(MultipartFile multipartFile,String fileName) throws Exception{
        StorePath  storePath = storageClient.uploadFile(multipartFile.getInputStream(), multipartFile.getSize(),
                FilenameUtils.getExtension(fileName), null);
        return storePath.getFullPath() ;
    }
    /**
     * 刪除文件
     */
    public String deleteFile(String fileUrl) {
        if (StringUtils.isEmpty(fileUrl)) {
            return "fileUrl == >>文件路徑為空...";
        }
        try {
            StorePath storePath = StorePath.parseFromUrl(fileUrl);
            storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
        } catch (Exception e) {
            return e.getMessage();
        }
        return "OK";
    }

    public byte[] downLoadFile(String filePath){
        StorePath storePath = StorePath.parseFromUrl(filePath);
        return storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadByteArray());
    }
}

6、測試界面

 

 

 7、常見問題

1).跨域錯誤:file origin does not match viewer’s
   解決方式:找到 viewer.js 中下方的這段代碼注釋掉

 

2).找不到文件錯誤:這個問題原因是因為沒有獲取到你本地或者服務器文件,也就是 pdf > web 目錄里沒有這個 pdf ,因為它默認是獲取這個目錄下的 pdf 文件

 

  解決方式:獲取本地文件或者服務器文件路徑,通過流的方式輸出到頁面上

3).文件損壞無法顯示問題:出現這個問題一般都是你的 url 沒有進行轉碼就直接請求到瀏覽器了,然后 url 存在的特殊字符會會讓瀏覽器誤認為你這個不是一個完整的鏈接

 

 

 解決方式:查看前端訪問的路徑是否使用 encodeURIComponent 轉碼

8、如何隱藏插件自帶的下載和打印功能?打開 viewer.html 文件,搜索 <button id="download" 在這個 button 按鈕加上一個屬性 style="visibility:hidden" 就 ok 了,如下圖

 

 

 


免責聲明!

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



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