In Summary:
I want to generate and download PDFs from external Vue components in Vue 3 project with Firebase
Background:
I’m relatively new to web development and I’m currently working on a project using Vue 3, Firebase, and PrimeVue Tailwind as a component library.
I have a page that displays a table of previously completed questionnaires (representing session performance evaluations). Next to each entry in the table, there’s an icon that, when clicked, should allow me to download the corresponding generated PDF with the results. Additionally, I’d like to be able to select multiple entries and download PDFs for all of them at once.
The challenge I’m facing is that I want the PDF to be generated from an HTML template of an external Vue component. However, including this component directly in the HTML of the view where I trigger the download causes issues. I attempted to include the component without displaying it, using the html2pdf package. However, the resulting PDF remained blank. While displaying the component resolves the issue, it’s not ideal as I don’t want it to be visible or loaded until the download button is clicked.
<template #body="{ data }">
<Button @click="downloadPDF(data)" icon="pi pi-download" />
<DocumentPDF v-if="showPDF" :evaluation="data" />
</template>
Additionally, I’d like the PDF to be generated by a Vue component because the compiled evaluation is quite complex. It requires two different objects to be filled or displayed correctly: a JSON object that provides the structure (pages, categories, fields, subfields) to dynamically generate the form, and an object with the answers fetched from Firebase, which does not have the same structure as the first object. Therefore, I also need to use some method to retrieve the corresponding field answers.
Another reason for wanting the PDF to be generated by a Vue component is that I’d like to display it using almost the same UI components that were used to compile it.
I’ve explored various solutions but haven’t been able to determine which one is best suited to my needs. Can anyone suggest the best solution for this scenario?