Note: This blog post was originally published on my personal blog Majid's
Have you ever wondered if you can download an HTML table as a PDF file? Recently, while working on a side project using Nuxt3, I ran into this same question. I needed to generate a table of data and make it shareable with others. I found many libraries that can do this, but none of them had a good example in Vue. So, I thought it might be useful to share my method with others.
To download an HTML table as a PDF file, we need to use two libraries:
dom-to-image
: This library allows capturing a screenshot of a DOM element and returning a data URI containing a PNG image.
jsPDF
: This library allows creating a PDF document in JavaScript.
Let's get started with the steps:
Step 1: Install the Libraries
npm install jspdf -S
npm install dom-to-image -S
Step 2: Create a PDF Document Now, we need to create a PDF document using the jsPDF constructor. Here's the code:
// new jsPDF(orientation, unit, dimensions, ...otherOptions)
const pdf = new jsPDF('l', 'pt', [tableWidth, tableHeight]);
as you can see, this constructor takes some options, we will use 3 of them
-
l
: The orientation of the PDF document.l
stands for landscape andp
stands for portrait. In this case,l
is used to create a landscape-oriented PDF. -
pt
: The unit of measurement used to specify the dimensions of the PDF document.pt
stands for points, which is a common unit of measurement for printed materials. -
[tableWidth, tableHeight]
: An array specifying the width and height of the PDF document in points. These values are based on the size of the HTML table being converted to a PDF.
Step 3: Add the HTML as an Image
-
We need to add the HTML table as an image to our PDF document using the
addImage
method. Here's the code:
// addImage(imageData, format, x, y, width, height, alias, compression, rotation)
pdf.addImage(imageData, 'PNG', 0, 0, tableWidth, tableHeight);
-
imageData
: the data of the image to be inserted (we don't have this image yet!) -
PNG
: the format of the image to be inserted. -
0, 0
: the X and Y coordinates of the image's top-left corner in the PDF document. -
tableWidth, tableHeight
: the width and height of the image to be inserted in the PDF document.
but since we don't have imageData
yet, and here is where we're going to use dom-to-image
library
Step 4: Capture the HTML Table as an Image
domtoimage.toPng(HTMLElement);
domtoimage.toPng
is a method provided by the dom-to-image
library which allows capturing a screenshot of a DOM element and returning a data URI containing a PNG image. The method takes the DOM element as an argument and returns a Promise that resolves with the data URI.
Step 5: Save the PDF File
pdf.save("table.pdf");
Here is a full vue
example
<template>
<div class="wrapper">
<table ref="table">
<thead>
<tr>
<th>Month</th>
<th>Revenue</th>
<th>Profit</th>
</tr>
</thead>
<tbody>
<tr>
<td>January</td>
<td>$10,000</td>
<td>$2,000</td>
</tr>
<tr>
<td>February</td>
<td>$15,000</td>
<td>$3,000</td>
</tr>
<tr>
<td>March</td>
<td>$12,000</td>
<td>$2,500</td>
</tr>
<tr>
<td>April</td>
<td>$20,000</td>
<td>$5,000</td>
</tr>
</tbody>
</table>
<button @click="onDownload">Download PDF</button>
</div>
</template>
<script setup>
import { ref } from "vue";
import { jsPDF } from "jspdf";
import domtoimage from "dom-to-image";
const table = ref(null);
const onDownload = () => {
const tableWidth = table.value.clientWidth;
const tableHeight = table.value.clientHeight;
// Convert HTML table to PNG image using dom-to-image
domtoimage.toPng(table.value).then((imageData) => {
// Create a new jsPDF document
const pdf = new jsPDF("l", "pt", [tableWidth, tableHeight]);
// Add the PNG image to the PDF document
pdf.addImage(imageData, "PNG", 0, 0, tableWidth, tableHeight);
// Save the PDF document
pdf.save("table.pdf");
});
};
</script>
Check the Codesandbox
Final notes
Creating PDF documents from HTML tables in Vue.js can be a powerful way to allow users to share data in a portable and professional format. In this example, we used the jsPDF library to generate a PDF document and the dom-to-image library to convert an HTML table to a PNG image that was added to the PDF. However, keep in mind that if you're using a custom font in your table, you may need to add the font to the PDF as well. Be sure to check the jsPDF documentation for further guidance on adding custom fonts to your PDF documents. Happy coding! 🧑🏻💻
Top comments (3)
How would you approach having multiple pages that have the same footer/header?
Looks like the current setup does not really include any default print sizes like A4 and multi page support.
This has nothing to do with Vue.
Thanks to the composition api for making it sounds like that 😅, but yes, it is not a much of a Vue , just a ref to catch the element and the onDownload method 👍