<input id="ohw05"></input>
  • <table id="ohw05"><menu id="ohw05"></menu></table>
  • <var id="ohw05"></var>
  • <code id="ohw05"><cite id="ohw05"></cite></code>
    <label id="ohw05"></label>
    <var id="ohw05"></var>
  • PDF.js Electron Viewer

    PDF.js 是基于 HTML5 解析與渲染 PDF 的 JavaScript 庫,由 Mozilla 主導開源。

    本文旨在介紹 PDF.jsElectron 里如何開始使用,實際嘗試了用其 API 或嵌入 HTML 的幾種方式。

    從零準備項目

    項目采用 Electron React Antd PDF.js 來實現,以下是從零準備項目的過程。

    Electron React

    這里用 electron-react-boilerplate 模板開始 Electron React 項目。

    # 獲取模板
    git clone --depth=1 \
    https://github.com/electron-react-boilerplate/electron-react-boilerplate \
    electron-pdf-viewer
    
    cd electron-pdf-viewer
    
    # 設定倉庫
    git remote set-url origin git@github.com:ikuokuo/electron-pdf-viewer.git
    # 如果想合并成一個初始提交
    #  https://stackoverflow.com/a/23486788
    git config --global alias.squash-all '!f(){ git reset $(git commit-tree HEAD^{tree} -m "${1:-A new start}");};f'
    git squash-all "first commit"
    git push -u origin main
    
    # 依賴
    npm install
    # 運行
    npm start
    # 打包
    npm run package
    

    準備編輯器(VSCode):

    code --install-extension dbaeumer.vscode-eslint
    code --install-extension dzannotti.vscode-babel-coloring
    code --install-extension EditorConfig.EditorConfig
    

    其他編輯器,可見 Editor Configuration

    Ant Design

    添加 antd 依賴:

    npm install antd
    

    之后,就可以快速布局頁面了,如下:

    PDF.js

    添加 pdfjs 依賴:

    npm install pdfjs-dist
    npm install -D worker-loader
    

    此外,準備 PDF 樣例進 static/,簡單用 Python 提供 HTTP 訪問:

    npm run static
    

    用于開發運行,正式運行可用 file:// 地址。

    PDF.js 渲染

    使用 API

    用 API 渲染頁面,可見官方 Examples

    1. 導入包

    import * as pdfjsLib from 'pdfjs-dist/webpack';
    

    2. 渲染頁面

    (async () => {
      // 獲取 doc
      const loadingTask = pdfjsLib.getDocument(url);
      const pdf = await loadingTask.promise;
    
      console.log(`PDF loaded, n=${pdf.numPages}`);
      setNumPages(pdf.numPages);
    
      // 獲取 page
      const page = await pdf.getPage(1);
    
      // 獲取 canvas
    
      const scale = 1.5;
      const viewport = page.getViewport({ scale });
      // Support HiDPI-screens.
      const outputScale = window.devicePixelRatio || 1;
    
      const canvas = canvasRef.current;
      if (canvas == null) return;
      const context = canvas.getContext('2d');
    
      canvas.width = Math.floor(viewport.width * outputScale);
      canvas.height = Math.floor(viewport.height * outputScale);
      canvas.style.width = `${Math.floor(viewport.width)}px`;
      canvas.style.height = `${Math.floor(viewport.height)}px`;
    
      const transform =
        outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null;
    
      // 渲染 page
      const renderContext = {
        canvasContext: context,
        transform,
        viewport,
      };
      await page.render(renderContext);
      console.log('Page rendered!');
    })();
    

    完整代碼,見 Pdfjs/index.tsx。效果如下:

    使用 Viewer API

    用 Viewer API 渲染,其在 pdfjs-dist/web/pdf_viewer 路徑下。

    1. 導入包

    import * as pdfjsLib from 'pdfjs-dist/webpack';
    import { PDFViewer, EventBus } from 'pdfjs-dist/web/pdf_viewer';
    import 'pdfjs-dist/web/pdf_viewer.css';
    

    2. 布局頁面

    <div className="viewer">
      <div>url={url}</div>
      <div>numPages={numPages}</div>
      <div ref={hrRef} />
      <div ref={containerRef} className="container">
        <div className="pdfViewer" />
      </div>
    </div>
    

    要求 absolute 定位:

    .viewer {
      position: relative;
    
      .container {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        overflow: scroll;
      }
    }
    

    3. 渲染 PDF

    const container = containerRef.current;
    if (container == null) return;
    
    if (hrRef.current) {
      container.style.top = `${hrRef.current.offsetTop}px`;
    }
    
    // 監聽事件,必須傳參 PDFViewer 為實例
    const eventBus = new EventBus(null);
    eventBus.on('pagesinit', () => {
      console.log('pagesinit');
    });
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    eventBus.on('pagesloaded', (e: any) => {
      console.log('pagesloaded');
      console.log(e);
      setNumPages(e.pagesCount);
    });
    eventBus.on('pagerendered', () => {
      console.log('pagerendered');
    });
    
    // 創建 PDFViewer
    const pdfViewer = new PDFViewer({
      container,
      eventBus,
      linkService: null,
      renderer: 'canvas',
      l10n: null,
    });
    
    // 導入 Document
    (async () => {
      const loadingTask = pdfjsLib.getDocument(url);
      const pdf = await loadingTask.promise;
      pdfViewer.setDocument(pdf);
    })();
    

    完整代碼,見 PdfViewer/index.tsx。效果如下:

    使用 Viewer HTML

    PDF.js 提供了在線演示的 viewer.html,不過 pdfjs-dist 里沒有,要自己編譯其源碼。

    編譯結果已放進 static/pdfjs/,可用 Electron Window 打開 web/viewer.html?file=x.pdf 或用 iframe 嵌入。

    如果自己重新編譯,過程如下:

    git clone -b master --depth=1 https://github.com/mozilla/pdf.js.git
    cd pdf.js
    
    # 安裝依賴
    npm install -g gulp-cli
    npm install
    
    # 開發運行
    gulp server
    # http://localhost:8888/web/viewer.html
    
    # 編譯發布
    gulp generic
    # build/generic/
    

    iframe 嵌入的話,也是打開 web/viewer.html?file=x.pdf

    <div className="viewerHTML">
      <div>pdfUrl={pdfUrl}</div>
      <div>pdfWebViewerUrl={pdfWebViewerUrl}</div>
      <iframe
        className="pdfViewer"
        title="PdfViewerHTML"
        src={`${pdfWebViewerUrl}?file=${pdfUrl}`}
      />
    </div>
    
    .viewerHTML {
      .pdfViewer {
        border: none;
        width: 100%;
        height: 100%;
      }
    }
    

    這里打開的 npm run static 提供的 HTTP 地址,效果如下:

    iframe 要打開本地 HTML 試了下沒成,如果想在 Electron + React 下這么用,還要研究下怎么弄。

    最后

    PDF.js 可以說是 Web 渲染 PDF 的不二選擇,很多 PDF Web Viewer 庫都是基于它實現的。

    GoCoding 個人實踐的經驗分享,可關注公眾號!

    posted @ 2021-12-15 17:53  GoCodingInMyWay  閱讀(104)  評論(0編輯  收藏  舉報
    国产美女a做受大片观看