今天在项目中实现pdf在线预览的功能的如图, 通过百度,查询合适的方法,最为简单的的是通过pdf.js的插件在前台展示。本以为是挺容易实现的,但都有莫名其妙的错误。

第一步:下载源码https://github.com/mozilla/pdf.js

第二步:构建PDF.js

ps:其实我们使用pdf.js,只需要构建后的内容,大家可以到我的百度云盘下载:https://pan.baidu.com/s/10j9rqnY-vkyLRQuxCWrhfQ 提取码:gigy ;下载后复制generic到到resource/static/ 下,可以改名为pdf(自定义)

第三步:

修改viewer.js

var DEFAULT_URL = 'compressed.tracemonkey-pldi-09.pdf'  里面是PDF的路径,这是默认加载pdf文件的路劲

第四步:在前端js中引用(在点击事件中)

var curWwwPath = window.document.location.href;
var pathName = window.document.location.pathname;
var pos = curWwwPath.indexOf(pathName);
var localhostPath = curWwwPath.substring(0, pos);
//调用pdfjs的viem.html页面来展示获得pdf
window.open(localhostPath + "/pdf/web/viewer.html?file=http://localhost:8083/previewPdf");

第四步:后台controller实现的代码

/**
  * 预览pdf文件
  * @param fileName
  */
    @RequestMapping(value = "/previewPdf", method = RequestMethod.GET)
    public void pdfStreamHandler(String fileName,HttpServletRequest request,HttpServletResponse response) {

        File file = new File("E:\\"+fileName);
        if (file.exists()){
            byte[] data = null;
            try {
                FileInputStream input = new FileInputStream(file);
                data = new byte[input.available()];
                input.read(data);
                response.getOutputStream().write(data);
                input.close();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }else{
            return;
        }
    }

开始以为这样子就可以访问到本地pdf文件,我发现我错了,不知道为什么通过这种方式调用viewer.html,fileName参数传递不过来,后面我把File file = new File("E:\\test.pdf");就能在前台读取到了pdf文件。(参数不能传递过来,原因不明)。

然后我想访问ipfs上的文件,它又不知道怎么传递参数,然后我就用两个方法实现在线预览ipfs上的pdfs文件,首先先通过ipfs的文件路径获取到文件的。然后再使用一个方法把获取到的数据展现在viewer.html上。

前台代码:

 //文件预览
    function previewPdf(obj) {
        //首先获得按钮列,然后获得行,再获得这行的所有列
        var $td = $(obj).parents('tr').children('td');
        //获得指定的列的值
        var fileName = $td.eq(0).text();
        var path = $td.eq(1).text();
        var url = "http://localhost:8083/tempDownloadFile?path=" + path + "&fileName" + fileName;
        $.ajax({
            type: 'POST',
            async: false,
            url: url,
            dataType: 'text',
            success: function (responseText) {
                if (responseText == "success") {
                    // alert(11)
                    var curWwwPath = window.document.location.href;
                    var pathName = window.document.location.pathname;
                    var pos = curWwwPath.indexOf(pathName);
                    var localhostPath = curWwwPath.substring(0, pos);
                    //调用pdfjs的viem.html页面来展示获得pdf
                    window.open(localhostPath + "/pdf/web/viewer.html?file=http://localhost:8083/previewPdf");
                }
            },
            error: function () {
                alert('发生错误');
            }
        });
    };

后台代码:

/**
     * 预览pdf文件
     */
    @RequestMapping(value = "/previewPdf", method = RequestMethod.GET)
    public void pdfStreamHandler(HttpServletRequest request, HttpServletResponse response) throws IOException {
        byte [] data = (byte[]) request.getSession().getAttribute("data");
        if (data != null) {
            response.getOutputStream().write(data);
        } else {
            return;
        }
        request.getSession().removeAttribute("data");
    }

    /**
     *  临时缓存pdf文件用于在线浏览
     * @param response
     */
    @RequestMapping("/tempDownloadFile")
    @ResponseBody
    public void tempDownloadFile(String path , String fileName , HttpServletRequest request, HttpServletResponse response) throws IOException {
        byte[] data = ipfsService.download(path);
        request.getSession().setAttribute("data",data);
        response.getWriter().write("success");
    }

展示:

http://localhost:8083/pdf/web/viewer.html?file=http://localhost:8083/previewPdf这样子的访问就是通过后台获取的pdf的流,然后通过在前台展示。

到此pdf.js结束了,不过本人还是不清楚这样子传递参数,为什么后台没法接受到,希望各位大神告诉一下小弟。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐