javascript - vueHtml2Pdf 渲染空白页面(Nuxt)

标签 javascript vue.js pdf nuxt.js

我正在使用vueHtml2Pdf将我的页面生成为 pdf,但是当我将内容包装在 VueHtml2pdf 标记中时,我的页面上不会呈现任何内容,但当我单击下载按钮时它会下载。 (Nuxt)

  methods: {
    downloadPDF() {
      this.$refs.html2Pdf.generatePdf()
    },
  },
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>



        <ArticleActions @download="downloadPDF()" />
    

    <client-only>
      <vue-html2pdf
        ref="html2Pdf"
        :show-layout="false"
        :enable-download="true"
        :pdf-quality="2"
        :manual-pagination="true"
        pdf-content-width="100%"
        :html-to-pdf-options="htmlToPdfOptions"
      >
        <section slot="pdf-content">
      <!-- content -->
          <div
            v-interpolation="{ newWindow: true }"
            class="articleContent__content"
            v-html="article.content"
          ></div>
      <!-- /content -->
        </section>
      </vue-html2pdf>
    </client-only>

最佳答案

我有一个 Nuxtv3 的工作解决方案(带有服务器端渲染)。在尝试了一堆不同的 vue 特定包(包括 vue-html2pdf)之后,我意识到其中大部分都是为 Vue2 编写的。

相反,我选择使用 html2pdf直接。

在需要添加将 html 转换为 pdf 的功能的组件中直接导入 html2pdf 时,Nuxt 会抛出以下错误:ReferenceError: self is not Defined。这本质上是因为导入库的行也在服务器端运行,并且当导入库时,它会尝试访问未在服务器端定义的变量。

我的解决方案是创建一个仅在客户端运行的自定义插件。在 Nuxtv3 中执行此操作非常简单,只需以 .client.ts 结尾文件名,而不是仅以 .ts 结尾。这是 plugins/html2pdf.client.ts 的样子:

import html2pdf from 'html2pdf.js'

export default defineNuxtPlugin(() => {
  // had to make a plugin because directly importing html2pdf.js in the component
  // where I need to use it was causing an error as the import would run on the server
  // side and html2pdf.js is a client-side-only library. This plugin runs on the
  // client side only (due to the .client extension) so it works fine.
  return {
    provide: {
      html2pdf: (element, options) => {
        return html2pdf(element, options)
      }
    }
  }
})

现在,我可以在我的组件中安全地使用它:

const { $html2pdf } = useNuxtApp()

function downloadPDF() {
  if (document) {
    const element = document.getElementById('html2pdf')

    // clone the element: https://stackoverflow.com/questions/60557116/html2pdf-wont-print-hidden-div-after-unhiding-it/60558415#60558415
    const clonedElement = element.cloneNode(true) as HTMLElement
    clonedElement.classList.remove('hidden')
    clonedElement.classList.add('block')
    // need to append to the document, otherwise the downloading doesn't start
    document.body.appendChild(clonedElement)

    // https://www.npmjs.com/package/html2pdf.js/v/0.9.0#options
    $html2pdf(clonedElement, {
      filename: 'filename.pdf',
      image: { type: 'png' },
      enableLinks: true
    })
    clonedElement.remove()
  }  
}

html2pdf的基本用法:https://www.npmjs.com/package/html2pdf.js/v/0.9.0#usage

html2pdf的配置:https://www.npmjs.com/package/html2pdf.js/v/0.9.0#options

关于javascript - vueHtml2Pdf 渲染空白页面(Nuxt),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70243553/

相关文章:

Javascript获取网页的最后修改

c# - 如何从 Pdf、Word 和 Excel 文档中提取文本?

pdf - 使用哪种类型的注释(或其他对象)?

pdf - 如何使用 PDFsharp 库测量文本长度

javascript - Ionic 3 在 IOS 设备中隐藏滚动条

javascript - SVG:显示重叠形状的平均颜色

javascript - Firebase 网络。检查数组中的对象是否具有特定值

javascript - Vuejs 组件未响应 "mouseleave"事件

javascript - VueJs Axios 和 Typescript

javascript - 迁移到 Vue 2.0 $on() 听不到 $emit()