pdf.js 是一块将pdf文件进行再加工然后页面展示的小插件,可以实现自定义水印、编辑下载打印权限等功能。

开发过程遇到很多问题,可以直接看最后一部分。

show time

1、下载 http://mozilla.github.io/pdf.js/getting_started/#download

 

 

 下载后的文件这样

 

 

 附一个下载地址 https://files.cnblogs.com/files/xiufengd/pdfjs-2.16.105-dist.zip?t=1667295509

2、服务端提供二进制流的文件 代码如下

  @GetMapping("/show")
    @ResponseBody
    public void showReportPDF(String id, @RequestHeader("Referer") String referer){
        HttpServletResponse response = ApplicationContextUtil.getHttpServletResponse();
        String Host = profiles.equals("test")?
                "testurl"
                :
                profiles.equals("prod")?
                        "produrl"
                        :
                        "";
     // 来源检测,文件一般都是比较重要的 所以想要检测同源
if(referer.indexOf(Host)==-1&&referer.indexOf("localhost:8080")==-1){ throw new BusinessException(GsonUtil.toJson(new Message(MessageCode.NOAUTH.getCode(),"无权限"))); } try {
       // reportService.getReportInputStream 是返回一个InputStream类型的方法 用于从数据库或者其他地方获取文件的InputStream流 BufferedInputStream br
= new BufferedInputStream(reportService.getReportInputStream(id)); byte[] buf = new byte[1024]; int len = 0; response.reset(); // 非常重要 response.setContentType("application/pdf");
       // 处理直接请求跨域问题 一定注意是用addHeader 而不是setHeader response.addHeader(
"Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE"); response.addHeader("Content-Disposition", "inline; filename=" + java.net.URLEncoder.encode(id+".pdf", "UTF-8"));        // 将文件流输出到response中 OutputStream out = response.getOutputStream(); while ((len = br.read(buf)) != -1) { out.write(buf, 0, len); out.flush(); } br.close(); out.close(); } catch (IOException e) { throw new RuntimeException(e); } }

3、前端  注意 调用要用原生的ajax 否则会造成展示的文件页面正确但是内容为空的情况!!!

            var xhr = new XMLHttpRequest();
                    xhr.open(
                        "get","http://localhost:8000/report/show?id=22222",
                        true
                    );
            // 注意类型是blob xhr.responseType
= "blob";
            // 如果有权限校验 记得添加header xhr.setRequestHeader(
"token", "222222"); xhr.onload = function() {
              // 将返回的response构建URL 然后传输到插件里 const url
= window.URL.createObjectURL(this.response); window.open("/pdf/web/viewer.html?file=" + url);
              //展示2秒钟后 将链接失效 方式连接泄露 setTimeout(()
=> window.URL.revokeObjectURL(url), 2000); }; xhr.send();

4、个性化设置

  如果想禁用下载、打印、复制之类的工作,想要编辑 pdf\web\viewer.html 这个文件 在header里添加以下代码

  

<script>
        // 禁止右键、区域选择和复制
        oncontextmenu="window.event.returnValue=false"
        oncopy      ="window.event.returnValue=false"
        ondragstart  ="window.event.returnValue=false"
        onselectstart="window.event.returnValue=false"
        // 禁止键盘操作
        window.onkeydown = window.onkeyup = window.onkeypress = function (event) {
            event.preventDefault(); // 阻止默认事件行为
            window.event.returnValue = false;
        }
        // 屏蔽功能按钮
        function onBodyLoad(){
            var appConfig = PDFViewerApplication.appConfig;
            appConfig.toolbar.viewBookmark.setAttribute('hidden', 'true');
            appConfig.secondaryToolbar.viewBookmarkButton.setAttribute('hidden', 'true');
            appConfig.toolbar.openFile.setAttribute('hidden', 'true');
            appConfig.secondaryToolbar.openFileButton.setAttribute('hidden', 'true');
            appConfig.toolbar.download.setAttribute('hidden', 'true');
            appConfig.secondaryToolbar.downloadButton.setAttribute('hidden', 'true');
            appConfig.toolbar.print.setAttribute('hidden', 'true');
            appConfig.secondaryToolbar.printButton.setAttribute('hidden', 'true');
        }
        // 禁止右键下载,打印
        function stop(){
            return false;
        }
        document.oncontextmenu = stop;
      </script>

 5、问题点

  5.1 打开新页面后一片空白,但是接口返回正常

    不能用axios来调用,要用最原始的ajax来调用

  5.2 页面正常打开,表格展示正常,但是文字不显示

    字体没有正确加载 ,将viewer.js的cMapUrl内容"../web/cmaps/"修改为“https://cdn.jsdelivr.net/npm/pdfjs-dist@2.16.105/cmaps/”

    

 

   5.3 工具栏图标没有正常加载,单独访问提示跨域

    pdf/web/images下的svg图片加载失败,转换成png图片并修改viewer.css里的引用即可

posted on 2022-11-01 17:56  程序员丁先生  阅读(255)  评论(0编辑  收藏  举报