Reputation: 31
I am using vueHtml2Pdf to generate my page to pdf, but when I wrap my content inside VueHtml2pdf tag nothing renders on my page, but it downloads when I click the download button. (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>
Upvotes: 2
Views: 2387
Reputation: 1
If someone looking for how to use html2pdf in nuxt 2.
import html2pdf from 'html2pdf.js'
export default (context, inject) => {
inject('html2pdf', html2pdf)
}
plugins: [
'@/plugins/axios',
......
{ src: '@/plugins/html-to-pdf', mode: 'client' },
],
methods: {
export() {
this.$html2pdf(this.$refs.document, {
margin: 1,
filename: 'file-name.pdf',
image: { type: 'jpeg', quality: 0.98 },
html2canvas: {
scale: 1,
dpi: 192,
letterRendering: true,
ignoreElements: true,
},
jsPDF: { unit: 'pt', format: 'a2', orientation: 'portrait' },
})
},
Upvotes: 0
Reputation: 406
I have a working solution for Nuxtv3 (with server-side rendering). After trying a bunch of different vue-specific packages, including vue-html2pdf
, I realized that most of them have been written for Vue2.
Instead, I chose to use html2pdf
directly.
Upon directly importing html2pdf
in the component where I need to add the functionality for converting html to pdf, Nuxt throws the following error: ReferenceError: self is not defined
. This essentially happens because the line where the library is being imported runs on the server side as well and when it is imported, it tries to access a variable that isn't defined on the server side.
My solution was to create a custom plugin that runs only on the client side. It is very simple to do this in Nuxtv3 by just ending the filename with .client.ts
as opposed to just .ts
. Here is what plugins/html2pdf.client.ts
looks like:
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)
}
}
}
})
Now, I can safely use it in my component as:
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()
}
}
Basic usage of html2pdf
: https://www.npmjs.com/package/html2pdf.js/v/0.9.0#usage
Configuration for html2pdf
: https://www.npmjs.com/package/html2pdf.js/v/0.9.0#options
Upvotes: 5