Creating a PDF document from HTML content using html2pdf in a Vue 3.js application: A step-by-step guide

I am currently exploring the possibility of converting my HTML content into a PDF format using the html2pdf library. So far, I have successfully achieved this with a simple one-file component where the HTML and a <button> within a <template> tag, along with all methods contained in the same file as shown below:

<template>
    <div ref="pdf">
        Hello, this is my awesome HTML content converted into a PDF
    </div>
    <button @click="generatePDF">
        Make PDF
    </button>
</template>
<script>
import html2pdf from "html2pdf.js"
export default {
    methods: {
        generatePDF() {
            const doc = this.$refs.pdf
            html2pdf(doc)
        },
    },
}
</script>
<style></style>

However, the issue here is that the solution mentioned above occupies space in the DOM, making everything visible to the user, which is something I wish to avoid. Additionally, establishing a parent-child relationship (such as moving the button to a parent component) doesn't work either, as the entire HTML structure still remains visible. Attempts to use v-if or v-show result in a blank PDF file.

Here are the questions I have:

  1. How can I generate a PDF file without displaying the HTML content to the user?
  2. Is it feasible to extract information (HTML) from different components and merge them into a single PDF file? If so, how can this be accomplished?

Answer №1

A while back, I encountered a similar issue with Angular. What caught my attention was

  1. Is it possible to generate a PDF file without revealing the HTML content to the user?

This task seems impossible because html2pdf relies on creating a canvas dynamically.

  1. How can I gather information (HTML) from multiple components and combine them into a single PDF document?

html2pdf has limited capabilities and doesn't fulfill our requirements. This is not achievable as well.

After trying for a week, I eventually switched to JSpdf, which offers more features to accomplish these tasks.

Once you set up the format and template in JSpdf, it becomes easier and more customizable for future use.

Answer №2

In order to download a PDF using html2pdf without revealing the HTML content to the user, I came up with this solution.

For those unfamiliar with tailwind CSS, the classes used in this code snippet may seem confusing.

The basic idea is to enclose the PDF inside a teleport container and then hide it from view by placing it inside a div with styles like display: absolute, z-index: -1.

<script setup lang="ts">
import { onMounted } from 'vue';
import html2pdf from 'html2pdf.js';

onMounted(() => {
    // These timing values are not optimized.
    setTimeout(() => exportToPDF(), 1000)
    // Emitting 'close' will unmount this component
    setTimeout(() => emit('close'), 1500)
})

function exportToPDF() {
    html2pdf(document.getElementById('pdf'), {
        filename: 'myFilename.pdf',
    });
}
</script>

<template>
    <teleport :to="'#modal-target'">
        <div class="absolute">
            <div id="pdf" class="w-[803px]">
              PDF CONTENT
            </div>
        </div>
    </teleport>
 </template>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Retrieve Javascript files from the local static directory

Currently, I am developing a small project with Nuxt JS and I am facing a challenge in calling some Javascript files from my static directory. When it comes to CSS files, I have been able to do it successfully using the following code: css: [ './stat ...

How can HtmlUnit be used to identify and address website pages that display errors?

I've encountered an issue while trying to access this Ajax page through my Java program using the HtmlUnit 2.15 API. It seems that the problem arises from a broken link to a missing file located here. This is the snippet of code I'm working with ...

Iterate through a specified number of elements in batches during each loop execution

Imagine we have an array like this: let numbers = [1,2,3,4,5,6,7,8,9,10] For example: If we want to create 5 sets with each pair of numbers in it, the result would look like this, set1 = [1,2] set2 = [2,4] set3 = [5,6] We can achieve this using the mod ...

Angular Material DatePicker: Day and Month selection without including the Year

Is there a way to customize an Angular Date Picker to show only Month and Day without the Year option? The provided link demonstrates a Month and Year picker, but I am looking to modify it for Month and Day selection. Changing YYYY to DD does not yield th ...

Ways to increase the field count in PHP seamlessly with the help of JavaScript, jQuery, or AJAX, without the need to

Within my Yii form, there is a text field labeled certificate_name. I am looking to create a functionality where clicking on the plus icon will increment the text field by one and display it below the previous field. Below is the PHP code snippet I am usi ...

Tips for accessing nested JSON values using Selenium

Here is a JSON snippet to work with: "ACCOUNT": { "AmountDue": "$36,812.99", "OutstandingBalance": "$27,142.27", "StatementTotal": "$9,670.72", "StatementDate": "12/6/2018", "DueByDate": "12/23/2018", ...

Retrieve various elements using a loop and dynamic identifiers (perhaps within a multi-dimensional array)

Apologies for the confusing title. I am currently working on a piece of code which can be found here: https://jsfiddle.net/8ers54s9/13/ This code creates a basic text area and compares it to a predefined array to identify common words within a string. If ...

Strategies to manage or prevent a timezone offset while deploying a Next.js application on Vercel

Is there a way to ensure that a React/Next.js App always displays the local time in CEST, regardless of the user's location? For example, if I receive GMT time from the backend and want to offset it to display the CEST timezone, how can I achieve this ...

Transferring PHP Array information to JavaScript

I'm facing an issue with transferring data from a PHP function querying a mySQL database to a JavaScript function for use in a plotly graph. Although I can successfully retrieve the data in PHP, I encounter a problem when trying to access it in my Jav ...

Leverage a Vue instance within the data() method

Although it's not the recommended practice, there are rare cases when it can be useful. For instance, I am currently utilizing an external JS library to display JSON content, and this particular component accepts an options attribute. Within this attr ...

Why does React-Perfect-Scrollbar not work properly when the height of an element is not specified in pixels?

Currently, I am developing a chat application with React 18 for its user interface. The app includes a sidebar that displays user profiles. To ensure the app fits within the browser window height, I've made the list of user profiles scrollable when n ...

Unable to load content: net::ERR_CONTENT_LENGTH_MISMATCH

Can someone help me understand what this error message means and how to fix it? This error is showing up in the console of Google Chrome version 33.0 on a Windows 7 machine. An error occurred while trying to load a resource: net::ERR_CONTENT_LENGTH_MISM ...

Implementing a function to load HTML pages upon clicking a button with JavaScript

I need help creating a button that loads an HTML page using JavaScript, without redirecting to the page. However, the current code I have is not loading the HTML page as desired. Here is the code snippet in question: <!DOCTYPE html> <html> &l ...

Integrate ruby code within a javascript string

I am looking to insert tfx-<%= @doc.doc[:b].metadata['filename']} %> into a JavaScript string called 'url' url = "<%= @document.doc[:a].url(response_content_disposition: ContentDisposition.attachment( [INSERT HERE] )) %>"; ...

Transferring information from a server action to a server component

Is there a way to transfer data from my server action, specifically the value of the temperature variable, to the Home server component in my nextJS14 app? I want to display this value in the jsx of my Home server component. How can I achieve this? impor ...

When the onClick event is triggered, the formatted time will be displayed using a combination of Reactive programming,

Greetings! I've been browsing for a while, but this is my first time asking a question. For an in and out board, I'm trying to implement a feature where employees click the "out" button, and using Vue.js v-on:click(), it should display "Out at 3 ...

Explore within another map and analyze the node to spot the differences

I have some questions about iterating through a JavaScript Object and using array functions in JavaScript. Let's assume I have the following variables: var json1 = "[{"id": 1, "name":"x"}, {"id": 2, "name":"y"}]"; var json2 = "[{"id": 1, "name":"x"}, ...

What methods can I use to identify the startup folder of a Node application in macOS?

I'm in the process of creating a versatile NodeJS server/app that is packaged as a prebuilt binary using pkg (https://www.npmjs.com/package/pkg) for Windows, Mac, and Linux. Upon initialization, the app needs to generate a default config.json file in ...

Incorporate an icon next to the thumb in Vuetifyjs Tick Slider

I am in search of a suitable icon to add, whether it's an SVG Icon or Fontawesome, I have no preference. Below is the code I am using in vuetifyjs: <v-slider v-model="value" :tick-labels="ticksLabels1" class="step-slider" ...

How to grab the information from a different webpage using jQuery

This code snippet shows the function in question: $.get(profileAddress, function(data){ alert(data); }) The purpose of this function is to display the source code of the page profileAddress in an alert message. Now, how can I ...