天天看點

Pdfjs-dist 填坑日記第一版

Pdfjs-dist 填坑日記

  • 第一版
    • 優點
    • 缺點
    • 第一版
    • 第二版

第一版

vue mobile 項目中一個需求是預覽pdf,需要能加水印,可以縮放,另外需要無污染零添加。找到了pdfjs-dist。

優點

H5實作,功能比較強大。

缺點

文檔真的一般。

第一版

網上找了個例子,寫上,發現好用。

let vm = this; 
             let url = xxxxx;
            var canvas = document.getElementById('the-canvas');
            PDFJS.getDocument(
                url
                ).then(function (pdf) {
                pdf.getPage(num).then(function (page) {
                    if (vm.initFlag) {
                        vm.scale = document.body.getBoundingClientRect().width / page.view[2];
                        vm.minScale = vm.scale;
                    }
                    
                    var viewport = page.getViewport(vm.scale);
                    var context = canvas.getContext('2d');
                    
                    vm.initFlag = false;
                     canvas.height = viewport.height;
                     canvas.width = viewport.width;
                    context.globalCompositeOperation='source-over';
                    context.globalAlpha=0.2;
                    var renderContext = {
                        canvasContext: context,
                        viewport: viewport
                    };
                    page.render(renderContext);
                    document.querySelector('.scroll-content-info').style.width = document.querySelector('#the-canvas').getBoundingClientRect().width + 'px';
                    vm.$refs.scroll.refresh();
                    Util.setLoading(!1);
                    !vm.pdfWaterMark && Util.getUserInfo(vm.addWaterMarker);
                });
            });
            PDFJS.getDocument({data: 
                    atob(this.pdfData),
                    cMapUrl: 'https://cdn.jsdelivr.net/npm/[email protected]/cmaps/',
                    cMapPacked: true
                }).then(function (pdfDoc_) { //初始化pdf
                vm.pdfDoc = pdfDoc_;
                vm.pageTotal = vm.pdfDoc.numPages;
                !vm.pdfWaterMark && Util.getUserInfo(vm.addWaterMarker);
            }).catch(function (err) {
                if (err) {
                    console.log(err)
                    vm.throwerr(vm.pdfurl)
                }
            })
           

第一個坑來了:

1、後端戰友的接口之前定的是傳回base64,可這裡的參數是個url。那麼去網上找發現參數可以直接傳data。

2、中文字元不顯示。發現可以加cMapUrl解決

修改如下:‘

url 替換成

{data:

atob(base64Str),

cMapUrl: ‘https://cdn.jsdelivr.net/npm/[email protected]/cmaps/’,

cMapPacked: true

}

第二版

第一版開開心心的寫好了,交給了産品經理。

突然問題又來了,原來的版本是基于canvas的 ,如果使用pdf縮放功能(自己實作)。那麼就需要對canvas進行重繪。這樣會導緻ui出現閃爍的情況,使用者體驗非常不好。那麼怎麼辦呢?

找了半天毫無頭緒,看看pdfjs-dist 源碼發現有svg的實作。發現 可以這麼用

let vm = this;
            PDFJS.getDocument({data: 
                    atob(Base64Str),
                    cMapUrl: 'https://cdn.jsdelivr.net/npm/[email protected]/cmaps/',
                    cMapPacked: true
                }).then(function(pdf) {
            var numPages = pdf.numPages;
            var MAX_NUM_PAGES = 5;
            var ii = Math.min(MAX_NUM_PAGES, numPages);
            var promise = Promise.resolve();
            for (var i = 1; i <= ii; i++) {
                if(document.querySelector('[name="page='+i+'"]')){
                    let container = document.querySelector('[name="page='+i+'"]').children[0];
                    
                    var viewport = vm.pdfPage.getViewport(vm.scale);
                    document.querySelector('.pageContainer').children[0].width.baseVal.value = viewport.width;
                    document.querySelector('.pageContainer').children[0].height.baseVal.value = viewport.height;
                    container.style.width = viewport.width + 'px';
                    container.style.height = viewport.height + 'px';
                    document.querySelector('.scroll-content-info').style.width = document.querySelector('.pageContainer').getBoundingClientRect().width + 'px';
                    return;
                }
                var anchor = document.createElement('a');
                anchor.setAttribute('name', 'page=' + i);
                anchor.setAttribute('class', 'pdfATag');
                anchor.setAttribute('title', 'Page ' + i);
                document.getElementsByClassName("scroll-content-info")[0].appendChild(anchor);

                // Using promise to fetch and render the next page
                promise = promise.then(function (pageNum, anchor) {
                return pdf.getPage(pageNum).then(function (page) {
                    vm.pdfPage = page;
                    var viewport = page.getViewport(vm.scale);
                    var container = document.createElement('div');
                    container.id = 'pageContainer' + pageNum;
                    container.className = 'pageContainer';
                    container.style.width = viewport.width + 'px';
                    container.style.height = viewport.height + 'px';
                    anchor.appendChild(container);

                    return page.getOperatorList().then(function (opList) {
                    var svgGfx = new PDFJS.SVGGraphics(page.commonObjs, page.objs);
                    return svgGfx.getSVG(opList, viewport).then(function (svg) {
                        container.appendChild(svg);
                        document.querySelector('.scroll-content-info').style.width = document.querySelector('.pageContainer').getBoundingClientRect().width + 'px';
                        vm.$refs.scroll.refresh();
                        Util.setLoading(!1);
                        !vm.pdfWaterMark && Util.getUserInfo(vm.addWaterMarker);
                    });
                    });
                });
                }.bind(null, i, anchor));
            }
            });
           

開不開心~~

Pdfjs-dist相關文檔:

https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions

https://mozilla.github.io/pdf.js/examples/index.html#interactive-examples

https://github.com/mozilla/pdf.js/tree/master/examples/mobile-viewer

https://blog.csdn.net/niedewang/article/details/80136635

繼續閱讀