vue-html2pdf icon indicating copy to clipboard operation
vue-html2pdf copied to clipboard

Blank PDF Created

Open Trimakas opened this issue 5 years ago • 40 comments

I've just copied and pasted the examples and I'm not getting diddly.. Just a blank page.. Any ideas?

Here is my code:

 `<div>
    <vue-html2pdf
      :show-layout="false"
      :float-layout="true"
      :enable-download="true"
      :preview-modal="true"
      :paginate-elements-by-height="1400"
      filename="hee hee"
      :pdf-quality="2"
      :manual-pagination="false"
      pdf-format="a4"
      pdf-orientation="landscape"
      pdf-content-width="800px"
      @progress="onProgress($event)"
      @hasStartedGeneration="hasStartedGeneration()"
      @hasGenerated="hasGenerated($event)"
      ref="html2Pdf"
    >
      <section slot="pdf-content">
          <h4>
              Title
          </h4>

          <span>
              Value
          </span>
      </section>
    </vue-html2pdf>
  </div>`

And then the method generateReport() { this.$refs.html2Pdf.generatePdf() }

I've included it as a component: components: { VueHtml2pdf },

and it imports fine import VueHtml2pdf from 'vue-html2pdf'

I am using Vuetify if that makes a difference.. But other than that I'm at a loss?

Trimakas avatar Oct 06 '20 20:10 Trimakas

One more thing, when I debug this this.$refs.html2Pdf I am getting a Vue Component. Which I believe is correct?

Trimakas avatar Oct 06 '20 20:10 Trimakas

Hi what version are you using?

kempsteven avatar Oct 06 '20 22:10 kempsteven

In my package.json I'm running "vue-html2pdf": "^1.8.0",

Trimakas avatar Oct 06 '20 22:10 Trimakas

And then here is my entire package.json

{ "name": "bella", "private": true, "dependencies": { "@mdi/font": "^5.5.55", "@rails/actioncable": "^6.0.0", "@rails/activestorage": "^6.0.0", "@rails/ujs": "^6.0.0", "@rails/webpacker": "4.2.2", "animate.css": "^3.7.2", "axios": "^0.19.2", "babel-preset-stage-2": "^6.24.1", "jspdf": "^2.1.1", "lodash": "^4.17.20", "stylus": "^0.54.7", "stylus-loader": "^3.0.2", "tiptap": "^1.29.1", "tiptap-extensions": "^1.31.1", "tiptap-vuetify": "^2.24.0", "turbolinks": "^5.2.0", "vue": "^2.6.11", "vue-axios": "^2.1.5", "vue-cookies": "^1.7.0", "vue-html2pdf": "^1.8.0", "vue-loader": "^15.9.0", "vue-lodash": "^2.1.2", "vue-moment": "^4.1.0", "vue-quill-editor": "^3.0.6", "vue-router": "^3.1.5", "vue-template-compiler": "^2.6.11", "vue-the-mask": "^0.11.1", "vuelidate": "^0.7.5", "vuetify": "^2.2.14", "vuex": "^3.1.2", "vuex-persistedstate": "^2.7.1" }, "version": "0.1.0", "devDependencies": { "babel-eslint": "^10.1.0", "eslint": "^6.8.0", "eslint-plugin-vue": "^6.2.2", "sass": "^1.26.10", "sass-loader": "^8.0.2", "webpack-dev-server": "^3.10.3" } }

Trimakas avatar Oct 06 '20 22:10 Trimakas

Hmm thats weird that should work, any errors on the console?

Also try looking at the demo repo here https://github.com/kempsteven/vue-html2pdf-demo

kempsteven avatar Oct 06 '20 22:10 kempsteven

Are you using nuxt.js or just vue?

kempsteven avatar Oct 06 '20 22:10 kempsteven

Yea just Vue.. and nothing in the console.. super weird..

Trimakas avatar Oct 06 '20 23:10 Trimakas

When I debug my Vue code and I look at what this this.$refs.html2Pdf captures I get the below info

VueComponent {_uid: 906, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …} $attrs: (...) $children: [] $createElement: ƒ (a,b,c,d) $el: div.vue-html2pdf $listeners: (...) $options: {parent: VueComponent, _parentVnode: VNode, propsData: {…}, _parentListeners: {…}, _renderChildren: Array(1), …} $parent: VueComponent {_uid: 905, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …} $refs: {pdfContent: section.content-wrapper} $root: Vue {_uid: 3, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …} $scopedSlots: {$stable: false, $key: undefined, $hasNormal: true, pdf-content: ƒ} $slots: {pdf-content: Array(1)} $store: Store {_committing: false, _actions: {…}, _actionSubscribers: Array(0), _mutations: {…}, _wrappedGetters: {…}, …} $vnode: VNode {tag: "vue-component-397-VueHtml2pdf", data: {…}, children: undefined, text: undefined, elm: div.vue-html2pdf, …} $vuetify: {…} closePreview: ƒ () downloadPdf: ƒ () enableDownload: (...) filename: (...) floatLayout: (...) generatePdf: ƒ () hasAlreadyParsed: (...) htmlToPdfOptions: (...) manualPagination: (...) paginateElementsByHeight: (...) paginationOfElements: ƒ () pdfContentWidth: (...) pdfFile: (...) pdfFormat: (...) pdfOrientation: (...) pdfQuality: (...) pdfWindow: (...) previewModal: (...) progress: (...) resetPagination: ƒ () setOptions: ƒ () showLayout: (...) validateProps: ƒ () _c: ƒ (a,b,c,d) _data: {__ob__: Observer} _directInactive: false _events: {progress: Array(1), hasStartedGeneration: Array(1), hasGenerated: Array(1)} _hasHookEvent: false _inactive: null _isBeingDestroyed: false _isDestroyed: false _isMounted: true _isVue: true _props: {…} _renderProxy: Proxy {_uid: 906, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …} _routerRoot: Vue {_uid: 3, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …} _self: VueComponent {_uid: 906, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …} _staticTrees: null _uid: 906 _vnode: VNode {tag: "div", data: {…}, children: Array(3), text: undefined, elm: div.vue-html2pdf, …} _watcher: Watcher {vm: VueComponent, deep: false, user: false, lazy: false, sync: false, …} _watchers: (4) [Watcher, Watcher, Watcher, Watcher] $data: (...) $isServer: (...) $moment: (...) $props: (...) $route: (...) $router: (...) $ssrContext: (...) lodash: (...) _: (...) get $attrs: ƒ reactiveGetter() set $attrs: ƒ reactiveSetter(newVal) get $listeners: ƒ reactiveGetter() set $listeners: ƒ reactiveSetter(newVal) get hasAlreadyParsed: ƒ proxyGetter() set hasAlreadyParsed: ƒ proxySetter(val) get pdfFile: ƒ proxyGetter() set pdfFile: ƒ proxySetter(val) get pdfWindow: ƒ proxyGetter() set pdfWindow: ƒ proxySetter(val) get progress: ƒ proxyGetter() set progress: ƒ proxySetter(val) __proto__: Vue

Trimakas avatar Oct 06 '20 23:10 Trimakas

but yea when I do this: this.$refs.html2Pdf.generatePdf() I just get undefined

Trimakas avatar Oct 06 '20 23:10 Trimakas

Not sure whats happening on your side, But can you try copy pasting this, this works for me:

<vue-html2pdf
      :show-layout="false"
      :float-layout="true"
      :enable-download="false"
      :preview-modal="true"
      filename="hehehe"
     :paginate-elements-by-height="1100"
     :pdf-quality="2"
     pdf-format="a4"
     pdf-orientation="portrait"
     pdf-content-width="800px"
     :manual-pagination="false"

      @progress="onProgress($event)"
      @startPagination="startPagination()"
      @hasPaginated="hasPaginated()"
      @beforeDownload="beforeDownload($event)"
      @hasDownloaded="hasDownloaded($event)"
      ref="html2Pdf"
    >
      <section slot="pdf-content">
          <h4>
              Title
          </h4>

          <span>
              Value
          </span>
      </section>
    </vue-html2pdf>
...
methods: {
   async downloadPdf() {
      this.$refs.html2Pdf.generatePdf()
    }
}
...

Result: image

kempsteven avatar Oct 07 '20 00:10 kempsteven

Hmm, I am getting some CORS errors now.. not sure why..

VM4772:1 Refused to connect to 'blob:https://bella.skuagency.com/c8441586-2ffd-4d29-b9f1-d3dbbd225ec8' because it violates the following Content Security Policy directive: "connect-src 'self' https: http://localhost:3035 ws://localhost:3035". (anonymous) @ VM4772:1 _callee$ @ vue-html2pdf.esm.js:229 tryCatch @ runtime.js:45 invoke @ runtime.js:271 prototype.<computed> @ runtime.js:97 asyncGeneratorStep @ vue-html2pdf.esm.js:3 _next @ vue-html2pdf.esm.js:5 Promise.then (async) asyncGeneratorStep @ vue-html2pdf.esm.js:3 _next @ vue-html2pdf.esm.js:5 Promise.then (async) asyncGeneratorStep @ vue-html2pdf.esm.js:3 _next @ vue-html2pdf.esm.js:5 (anonymous) @ vue-html2pdf.esm.js:5 (anonymous) @ vue-html2pdf.esm.js:5 downloadPdf @ vue-html2pdf.esm.js:252 paginationOfElements @ vue-html2pdf.esm.js:176 generatePdf @ vue-html2pdf.esm.js:106 _callee$ @ edit_and_send_contract.vue:302 tryCatch @ runtime.js:45 invoke @ runtime.js:271 prototype.<computed> @ runtime.js:97 asyncGeneratorStep @ edit_and_send_contract.vue?c69a:1 _next @ edit_and_send_contract.vue?c69a:1 (anonymous) @ edit_and_send_contract.vue?c69a:1 (anonymous) @ edit_and_send_contract.vue?c69a:1 generateReport @ edit_and_send_contract.vue:302 invokeWithErrorHandling @ vue.runtime.esm.js:1888 invoker @ vue.runtime.esm.js:2224 invokeWithErrorHandling @ vue.runtime.esm.js:1888 Vue.$emit @ vue.runtime.esm.js:3872 click @ vuetify.js:3344 invokeWithErrorHandling @ vue.runtime.esm.js:1888 invoker @ vue.runtime.esm.js:2224 original._wrapper @ vue.runtime.esm.js:6934 VM4772:1 Refused to connect to 'blob:https://bella.skuagency.com/c8441586-2ffd-4d29-b9f1-d3dbbd225ec8' because it violates the document's Content Security Policy. (anonymous) @ VM4772:1 _callee$ @ vue-html2pdf.esm.js:229 tryCatch @ runtime.js:45 invoke @ runtime.js:271 prototype.<computed> @ runtime.js:97 asyncGeneratorStep @ vue-html2pdf.esm.js:3 _next @ vue-html2pdf.esm.js:5 Promise.then (async) asyncGeneratorStep @ vue-html2pdf.esm.js:3 _next @ vue-html2pdf.esm.js:5 Promise.then (async) asyncGeneratorStep @ vue-html2pdf.esm.js:3 _next @ vue-html2pdf.esm.js:5 (anonymous) @ vue-html2pdf.esm.js:5 (anonymous) @ vue-html2pdf.esm.js:5 downloadPdf @ vue-html2pdf.esm.js:252 paginationOfElements @ vue-html2pdf.esm.js:176 generatePdf @ vue-html2pdf.esm.js:106 _callee$ @ edit_and_send_contract.vue:302 tryCatch @ runtime.js:45 invoke @ runtime.js:271 prototype.<computed> @ runtime.js:97 asyncGeneratorStep @ edit_and_send_contract.vue?c69a:1 _next @ edit_and_send_contract.vue?c69a:1 (anonymous) @ edit_and_send_contract.vue?c69a:1 (anonymous) @ edit_and_send_contract.vue?c69a:1 generateReport @ edit_and_send_contract.vue:302 invokeWithErrorHandling @ vue.runtime.esm.js:1888 invoker @ vue.runtime.esm.js:2224 invokeWithErrorHandling @ vue.runtime.esm.js:1888 Vue.$emit @ vue.runtime.esm.js:3872 click @ vuetify.js:3344 invokeWithErrorHandling @ vue.runtime.esm.js:1888 invoker @ vue.runtime.esm.js:2224 original._wrapper @ vue.runtime.esm.js:6934 VM4772:1 Uncaught (in promise) TypeError: Failed to fetch at <anonymous>:1:876 at VueComponent._callee$ (vue-html2pdf.esm.js:229) at tryCatch (runtime.js:45) at Generator.invoke [as _invoke] (runtime.js:271) at Generator.prototype.<computed> [as next] (runtime.js:97) at asyncGeneratorStep (vue-html2pdf.esm.js:3) at _next (vue-html2pdf.esm.js:5)

Trimakas avatar Oct 07 '20 13:10 Trimakas

I did notice in another post here that you can pass options along to HTML2pdf.. but I'm not sure how? Any ideas?

Trimakas avatar Oct 07 '20 15:10 Trimakas

You can see here at the docs to get the full details of that.

Using the props html-to-pdf-options, you can configure the whole html2pdf.js options, here is a sample

To get full control of the html2pdf.js you can use the @beforeDownload event, see details here

kempsteven avatar Oct 07 '20 22:10 kempsteven

@Trimakas - I encountered this error before you need to control the css .vue-html2pdf .layout-container in order for this to work on your end. See screenshot: image

As you can see I have to override the default css

jeffersonbabuyo avatar Oct 19 '20 17:10 jeffersonbabuyo

Hi i'm facing this issue, currently on nuxt 2.14.6, no error on console. using show-layout the template is there but when generated just blank white pdf, testing on chrome, firefox, and safari.

already following your code for nuxt using client only

AndhikaR avatar Jan 20 '21 06:01 AndhikaR

I have exactly the same issue. Doesn't make any difference whether the layout is set to visible or not, and I'm currently only trying to render some simple test paragraphs. I just get a blank white PDF. @jeffersonbabuyo's workaround didn't do anything.

I'm not getting any errors, and the UI is behaving as expected. Can't see anything wrong.

For the record, this is is the code I'm using, on plain vue.js: <vue-html2pdf :show-layout="false" :preview-modal="true" :paginate-elements-by-height="1400" :filename="getDownloadName()" :pdf-quality="2" :manual-pagination="false" pdf-format="a4" pdf-orientation="portrait" pdf-content-width="100%" ref="reportPdf"> <section slot="pdf-content"> <div class="pdf-content"> <section style="background:#ff6a00"> <p style="color:#000">This should appear in the PDF</p> <p style="color:#fff">This should appear in the PDF</p> <p style="color:#000">This should appear in the PDF</p> <p style="color:#fff">This should appear in the PDF</p> <p style="color:#000">This should appear in the PDF</p> <p style="color:#fff">This should appear in the PDF</p> <p style="color:#000">This should appear in the PDF</p> <p style="color:#fff">This should appear in the PDF</p> <p style="color:#000">This should appear in the PDF</p> <p style="color:#fff">This should appear in the PDF</p> </section> </div> </section> </vue-html2pdf>

I'm using vue-html2pdf 1.8.0 on vue 2.6.12.

geoffbeaumont avatar Mar 02 '21 14:03 geoffbeaumont

Encountering the same issue. Copy/pasted the example at https://vue-html2pdf-demo.netlify.app/ and it renders 4 blank pages. No errors in console.

jpcarpenter avatar Mar 03 '21 17:03 jpcarpenter

Hi guys, life is so busy i apologize, but I'll try to find time for this maybe this weekend. @geoffbeaumont I will try & re create that

@jpcarpenter @AndhikaR can you provide your code please?

kempsteven avatar Mar 04 '21 03:03 kempsteven

I've actually found a workaround to the issue. I was rendering the <vue-html2pdf></vue-html2pdf> on a template with other data initially. I'm now rendering it on it's own dedicated page without any other data and it is working as expected. Not sure what was interfering with it.

jpcarpenter avatar Mar 04 '21 03:03 jpcarpenter

i already make it working, but i forgot which setting that make it work, this is my setting, i guess its allowTaint / useCORS/proxy

{
	margin: 6,  
	filename: this.recipe.title + '.pdf',
	image: {
		type: 'jpeg',
		quality: 1
	},
	pagebreak: {
		mode: ['css', 'legacy'],
		avoid: '.page-breaker'
	},
	html2canvas: {
		scale: 1,
		proxy: 'http://localhost:3000',
		useCORS: true,
		allowTaint: true,
		scrollX: 0,
		scrollY: 0
	},
	jsPDF: {
		format: 'letter',
		orientation: 'portrait'
	}
}

AndhikaR avatar Mar 04 '21 03:03 AndhikaR

I had the same problem and it has been solved by placing the component that contains the vue-html2pdf as the first element on the page. I don't understand why this happens, any ideas?

caroguerrerosilvera avatar Apr 30 '21 08:04 caroguerrerosilvera

This is happening for me. I've tried a million different solutions, none work. Occasionally I see something show up but not all of what I expect. I am thinking it is a timing issue. Is there a way to have it wait until everything is drawn, or a delay or something?

kinoli avatar May 30 '21 14:05 kinoli

Having this same issue, tried all solutions here and none is working

meckyblaze avatar Jun 07 '21 19:06 meckyblaze

I never actually solved this issue either – the issue kept happening for whatever reason. I ended up making a component with data that made up my PDF, then set up express + puppeteer. I then submit the data from my component to the express endpoint and handle it with puppeteer from there.

jpcarpenter avatar Jun 07 '21 20:06 jpcarpenter

I've actually found a workaround to the issue. I was rendering the <vue-html2pdf></vue-html2pdf> on a template with other data initially. I'm now rendering it on it's own dedicated page without any other data and it is working as expected. Not sure what was interfering with it.

This works, but then I need to find a way to import the component into the parent component... Importing into parent component with data doesn't work either... Any help will be much appreciated

meckyblaze avatar Jun 07 '21 20:06 meckyblaze

@meckyblaze you possibly could emit an event to the parent component with the data you need.

jpcarpenter avatar Jun 07 '21 20:06 jpcarpenter

This issue is due to html2canvas. You need to set the scrollX and scrollY to 0, as any scroll down the page will affect the html2canvas screenshot. Adding this prop will fix it for you.

:html-to-pdf-options="{
  margin: 10,
  filename: 'some-file-name',
  html2canvas: {
    scrollX: 0,
    scrollY: 0,
  },
}"

kinoli avatar Jun 07 '21 20:06 kinoli

:html-to-pdf-options="{ margin: 10, filename: 'some-file-name', html2canvas: { scrollX: 0, scrollY: 0, }, }"

You're a life saver... Thanks a lot

meckyblaze avatar Jun 07 '21 20:06 meckyblaze

@jpcarpenter and @kinoli you both saved me hours of debugging I appreciate.

meckyblaze avatar Jun 07 '21 20:06 meckyblaze

i already make it working, but i forgot which setting that make it work, this is my setting, i guess its allowTaint / useCORS/proxy

{
	margin: 6,  
	filename: this.recipe.title + '.pdf',
	image: {
		type: 'jpeg',
		quality: 1
	},
	pagebreak: {
		mode: ['css', 'legacy'],
		avoid: '.page-breaker'
	},
	html2canvas: {
		scale: 1,
		proxy: 'http://localhost:3000',
		useCORS: true,
		allowTaint: true,
		scrollX: 0,
		scrollY: 0
	},
	jsPDF: {
		format: 'letter',
		orientation: 'portrait'
	}
}

thanks its worked for me

javadrohani avatar Feb 21 '22 06:02 javadrohani