kempsteven / vue-html2pdf

vue-html2pdf converts any vue component or element into PDF, vue-html2pdf is basically a vue wrapper only and uses html2pdf.js behind the scenes.
https://www.npmjs.com/package/vue-html2pdf
MIT License
432 stars 75 forks source link

Blank PDF Created #34

Open Trimakas opened 3 years ago

Trimakas commented 3 years ago

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 commented 3 years ago

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

kempsteven commented 3 years ago

Hi what version are you using?

Trimakas commented 3 years ago

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

Trimakas commented 3 years ago

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" } }

kempsteven commented 3 years ago

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 commented 3 years ago

Are you using nuxt.js or just vue?

Trimakas commented 3 years ago

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

Trimakas commented 3 years ago

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 commented 3 years ago

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

kempsteven commented 3 years ago

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

Trimakas commented 3 years ago

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 commented 3 years ago

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

kempsteven commented 3 years ago

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

jeffersonbabuyo commented 3 years ago

@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

AndhikaR commented 3 years ago

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

geoffbeaumont commented 3 years ago

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">

This should appear in the PDF

This should appear in the PDF

This should appear in the PDF

This should appear in the PDF

This should appear in the PDF

This should appear in the PDF

This should appear in the PDF

This should appear in the PDF

This should appear in the PDF

This should appear in the PDF

                    </vue-html2pdf>`

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

jpcarpenter commented 3 years ago

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.

kempsteven commented 3 years ago

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?

jpcarpenter commented 3 years ago

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.

AndhikaR commented 3 years ago

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'
    }
}
caroguerrerosilvera commented 3 years ago

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?

kinoli commented 3 years ago

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?

meckyblaze commented 3 years ago

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

jpcarpenter commented 3 years ago

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.

meckyblaze commented 3 years ago

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

jpcarpenter commented 3 years ago

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

kinoli commented 3 years ago

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,
  },
}"
meckyblaze commented 3 years ago

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

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

meckyblaze commented 3 years ago

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

javadrohani commented 2 years ago

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

alidrus commented 2 years ago

Hi, I am having this same exact problem of the page rendering blank when I use my own component within the page. The component consists of a table with data loaded into it via an AJAX call. I've provided the pastebin link for the page containing vue-html2pdf and the component that is being used below:

The parent component: ./Daily.vue

The child component: ./Daily/TabularData.vue

Any help would be appreciated. Thanks in advance

joyal7701 commented 2 years ago

Hii, this generates blank pdf for me:

`
<vue3-html2pdf :show-layout="false" :float-layout="true" :enable-download="true" :preview-modal="true" :paginate-elements-by-height="1400" filename="invoice" :pdf-quality="2" :manual-pagination="false" pdf-format="a4" :pdf-margin="10" pdf-orientation="portrait" pdf-content-width="800px" @progress="onProgress($event)" ref="html2Pdf"

hii

`

function: ` <img :style="{ cursor: 'pointer' }" src="../assets/images/download-arrow.png" alt="«" @click="generatePDF()" />

generatePDF() { this.$refs.html2Pdf.generatePdf(); },`

Please help me as soon as possible. I have a strict deadline.

mJeromeDiaz commented 2 years ago

@joyal7701 have you try
html2canvas: { scrollX: 0, scrollY: 0 },

joyal7701 commented 2 years ago

@joyal7701 have you try html2canvas: { scrollX: 0, scrollY: 0 },

@mJeromeDiaz Where I have to put that? any reference link?

Gabrodriguez8i commented 2 years ago

tambien tengo el error, ya coloqué:

html2canvas: { scrollX: 0, scrollY: 0 },

pero de todas formas me tira error, aunque solo me genera el pdf cuando la tabla está vacia más no cuando se llama la api y se cargan los datos, tenia la ultima version y ahora instalé la version "vue-html2pdf": "^1.6.6", pero de igual formas tengo el error

eldeeno commented 1 year ago

Hello, I am having the blank pdf issue here but mine is a bit different. I am looping through returned api data to generate (n) number of report pages in the pdf file, which comes from a different component. It works when n=20, but generates (n) number of blank pages on the pdf when the api data count exceeds 20. like 31, 40, 60... I have tried most solutions suggested up here but all didn't work for me. Any idea guys?

carmenAimee commented 1 year ago

Hello, I am having the blank pdf issue here but mine is a bit different. I am looping through returned api data to generate (n) number of report pages in the pdf file, which comes from a different component. It works when n=20, but generates (n) number of blank pages on the pdf when the api data count exceeds 20. like 31, 40, 60... I have tried most solutions suggested up here but all didn't work for me. Any idea guys?

I have the same problem, the solution I found was to split the pdf in my case the maximum number is 40 bue now I have the problem that does not respect the page break, my header is placed at the bottom of the previous page. Someone knows how to fix this

eldeeno commented 1 year ago

Hello, I am having the blank pdf issue here but mine is a bit different. I am looping through returned api data to generate (n) number of report pages in the pdf file, which comes from a different component. It works when n=20, but generates (n) number of blank pages on the pdf when the api data count exceeds 20. like 31, 40, 60... I have tried most solutions suggested up here but all didn't work for me. Any idea guys?

I have the same problem, the solution I found was to split the pdf in my case the maximum number is 40 bue now I have the problem that does not respect the page break, my header is placed at the bottom of the previous page. Someone knows how to fix this

I will try splitting the pdf to see if it will work. For your own issue, try giving your page height by either adding this prop "paginate-elements-by-height : 1400" to your vue-html2pdf component. or you could give the section tag a "pdf-item" class and then a height in css.

Makksr commented 1 year ago

Hello, I am having the blank pdf issue here but mine is a bit different. I am looping through returned api data to generate (n) number of report pages in the pdf file, which comes from a different component. It works when n=20, but generates (n) number of blank pages on the pdf when the api data count exceeds 20. like 31, 40, 60... I have tried most solutions suggested up here but all didn't work for me. Any idea guys?

@eldeeno Did you find any solution for that . I am getting same issue like it works till 20 component, more than that all pages starts coming blank in pdf

eldeeno commented 1 year ago

@Makksr I just had to break the returned backend records into batches of not-more-than-20 in each. So when a particular batch button is clicked it will generate only 20 pdfs or less.