Vue3 で PDF をプレビューして印刷する 2 つの方法

プロジェクト シナリオ: バックグラウンド インターフェイスはデータを要求し、PDF ドキュメントへのリンクを返し、vue3 ページで PDF をプレビューおよび印刷できます。

以前のVue2プロジェクトではvue-pdfプラグインを使ってPDFのプレビューと印刷を行っていましたが、vue3ではサポートされておらず、プラグインを変更するしかないので、テスト後、いくつかの落とし穴を踏んでまとめました次の 2 つの方法:

方法 1: vue-pdf-embed  pdfjs-distを使用する

①まず、この2つのプラグインの依存関係をインストールします

pnpm install vue-pdf-embed
pnpm install pdfjs-dist2.0.943

その際、pdfjs-dist のインストール時に問題が発生しました.バージョン番号を指定しなかったため、コンソールにエラーが報告されました.いくつかの記事を読んだ後、いくつかのブロガーがバージョン 2.0.943 をインストールすることを提案したので、コマンドを再入力しましたこのバージョンをインストールしました。

②関連するコードをページに書く

// 引入插件
import VuePdfEmbed from 'vue-pdf-embed'
import * as pdfjsLib from 'pdfjs-dist'
//定义
const state = reactive({
    source: '', // 预览pdf文件地址
    pageNum: 0, // 当前页面
    scale: 1, // 缩放比例
    numPages: 0 // 总页数
})
const scale = computed(() => `transform:scale(${state.scale})`)
<div>
      // 操作按钮
      <div class="page-tool">
        <div class="page-tool-item" @click="lastPage">上一页</div>
        <div class="page-tool-item" @click="nextPage">下一页</div>
        <div class="page-tool-item">{
   
   { state.pageNum }}/{
   
   { state.numPages }}</div>
        <div class="page-tool-item" @click="pageZoomOut">放大</div>
        <div class="page-tool-item" @click="pageZoomIn">缩小</div>
     </div>
     //pdf预览
     <vue-pdf-embed ref='pdf' :source="state.source" :style="scale" :page="state.pageNum" class="vue-pdf-embed" />
 </div>
<script setup>
    onMounted(()=>{
        getPdfUrl(pdfUrl)  // pdfUrl即url地址链接
    })
    function getPdfUrl(data){
        state.source = data
        pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdf.worker.js'
        const loadingTask = pdfjsLib.getDocument(data)
        loadingTask.promise.then(pdf => {
            state.numPages = pdf.numPages
        })
    }
    // 上一页
    function lastPage() {
        if (state.pageNum > 1) {
            state.pageNum -= 1
        }
    }
    // 下一页
    function nextPage() {
        if (state.pageNum < state.numPages) {
            state.pageNum += 1
        }
    }
    // 放大
    function pageZoomOut() {
        if (state.scale < 2) {
            state.scale += 0.1
        }
    }
    // 缩小
    function pageZoomIn() {
        if (state.scale > 1) {
            state.scale -= 0.1
        }
    }
</script>

見栄えを良くするために、アクションボタンのスタイルを書きました

<style lang="scss" scoped>
    .page-tool {
        display: flex;
        position: absolute;
        top: 5px;
        left: 50%;
        z-index: 100;
        transform: translateX(-50%);
        align-items: center;
        background: rgb(66 66 66);
        color: white;
        border-radius: 19px;
        cursor: pointer;
        justify-content: center;
        font-size: 15px;
    }
    .page-tool-item {
        padding: 4px 10px;
        cursor: pointer;
    }
</style>

 最終的な実現効果:

印刷:

const { proxy } = getCurrentInstance()

<div @click='print'>打印</div>
<script setup>
    function print(){
        proxy.$refs['pdf'].print()
    }
</script>

 方法 2: pdfjs-dist、キャンバス レンダリング、pdf.js 印刷を使用する

  説明: pdf.js はキャンバス データを印刷できるので、このプラグインを選択します

①まずは依存関係をインストール

pnpm install pdfjs-dist

 インストール後、プロジェクトの node_modules フォルダーで、pdfjs-dist ->build->pdf.worker.js ファイルを見つけてコピーし、パブリック ルート ディレクトリに配置してから、pdfjs-dist ->cmaps フォルダーを見つけます。次に示すように、public->static フォルダーに移動します。

②print.jsをダウンロードしてプロジェクトに入れ、使用するページのメソッドを導入し、メソッドを呼び出す

具体的には、次のブログ投稿を参照します: print.js_printjs_@我不知道你的博客-CSDN ブログを使用したフロントエンド印刷

③コードの実装

// 打印按钮
<div @click="print">打印</div> 

//pdf预览显示
<div>
    <div id="printDom" ref="printDom">
        <div v-for="item in state.numPages" :key="item">
            <canvas :id="`pdfCanvas-${item}`" :ref="`pdfCanvas-${item}`" />
        </div>
    </div>
</div>

<script setup>
    import * as pdfjsLib from 'pdfjs-dist' //引入pdfjs-dist
    import Print from '@/assets/js/print'  //引入print.js
    const { proxy } = getCurrentInstance()
    const state = reactive({
        source: '', // 预览pdf文件地址
        pageNum: 0, // 当前页面
        scale: 1, // 缩放比例
        numPages: 0, // 总页数
        pdfCtx: null // pdf对象
    })
    onMounted(()=>{
        pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdf.worker.js'
        const loadingTask = pdfjsLib.getDocument({
            url: pdfUrl,  //这里的pdfUrl即pdf的链接地址
            cMapUrl: '../../../../static/cmaps/',
            cMapPacked: true
        })
        loadingTask.promise.then(pdf => {
            // console.log('页数', pdf.numPages)
            state.numPages = pdf.numPages
            state.pdfCtx = pdf
            nextTick(() => {
                renderPdf()
            })
        })
    })
    const renderPdf = (num = 1) => {
        state.pdfCtx.getPage(num).then(page => {
            const canvas = document.getElementById(`pdfCanvas-${num}`)
            const ctx = canvas.getContext('2d')
            const viewport = page.getViewport(1.6)
            canvas.height = viewport.height
            canvas.width = viewport.width
            page.render({
                canvasContext: ctx,
                viewport: viewport
            })
            if (num < state.numPages) {
                renderPdf(num + 1)
            }
        })
    }
    //打印
    function print(){
        Print(proxy.$refs['printDom'])
    }
</script>

おすすめ

転載: blog.csdn.net/qing_jian0119/article/details/128739730