{"id":12923,"date":"2025-03-17T19:35:52","date_gmt":"2025-03-17T19:35:52","guid":{"rendered":"https:\/\/codevoweb.com\/?p=12923"},"modified":"2025-03-17T19:35:55","modified_gmt":"2025-03-17T19:35:55","slug":"how-to-convert-html-to-pdf-in-javascript-example-with-code","status":"publish","type":"post","link":"https:\/\/codevoweb.com\/how-to-convert-html-to-pdf-in-javascript-example-with-code\/","title":{"rendered":"How to Convert HTML to PDF in JavaScript &#8211; Example with Code"},"content":{"rendered":"\n<p>A few weeks ago, I ran into a challenge at work\u2014I needed to generate PDFs from dynamically generated HTML content. Whether it was for invoices, reports, or downloadable documents, the requirement was clear: convert HTML to a well-formatted PDF using JavaScript.<\/p>\n\n\n\n<p>At first, I assumed it would be straightforward, but I quickly realized there were multiple ways to achieve this, each with its own strengths and trade-offs. After testing different libraries and methods, I found the best solutions using <strong>jsPDF, html2pdf, and Puppeteer<\/strong>.<\/p>\n\n\n\n<p>In this article, we&#8217;ll <strong>dive deep into these tools<\/strong>, explore how they work, and walk through step-by-step examples so you can seamlessly integrate HTML-to-PDF conversion into your own projects.<\/p>\n\n\n\n<p>But that\u2019s just the beginning! In upcoming articles, we\u2019ll <strong>take a closer look at each library<\/strong>, breaking down their advanced features, customization options, and real-world applications. Whether you need <strong>client-side or server-side PDF generation<\/strong>, we\u2019ll help you choose the right approach for your specific needs.<\/p>\n\n\n\n<p>Let\u2019s get started! \ud83d\ude80<\/p>\n\n\n\n<p>More practice<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"\/how-to-validate-react-js-forms-without-external-libraries\/\">How to Validate React.js Forms Without External Libraries<\/a><\/li>\n\n\n\n<li><a href=\"\/setup-and-use-nextauth-in-nextjs-14-app-directory\/\">Setup and Use NextAuth.js in Next.js 14 App Directory<\/a><\/li>\n\n\n\n<li><a href=\"\/implement-authentication-with-nextauth-in-nextjs-14\/\">Implement Authentication with NextAuth in Next.js 14<\/a><\/li>\n\n\n\n<li><a href=\"\/google-and-github-oauth-with-nextauth-in-nextjs-14\/\">Set up Google and GitHub OAuth with NextAuth in Next.js 14<\/a><\/li>\n\n\n\n<li><a href=\"\/implement-authentication-with-supabase-in-nextjs-14\/\">Implement Authentication with Supabase in Next.js 14<\/a><\/li>\n\n\n\n<li><a href=\"\/setup-google-github-oauth-with-supabase-in-nextjs-14\/\">Setup Google and GitHub OAuth with Supabase in Next.js 14<\/a><\/li>\n\n\n\n<li><a href=\"\/implement-authentication-with-trpc-in-nextjs-14\/\">Implement Authentication with tRPC in Next.js 14<\/a><\/li>\n\n\n\n<li><a href=\"\/implement-authentication-with-trpc-api-in-nextjs-14\/\">Implement Authentication with tRPC API in Next.js 14<\/a><\/li>\n\n\n\n<li><a href=\"\/using-trpc-with-nextjs-14-react-query-and-prisma\/\">Using tRPC with Next.js 14, React Query and Prisma<\/a><\/li>\n\n\n\n<li><a href=\"\/how-to-set-up-and-use-react-query-in-next-js-14\/\">How to Set Up and Use React Query in Next.js 14<\/a><\/li>\n\n\n\n<li><a href=\"\/using-react-query-with-supabase-in-next-js-app-router\/\">Using React Query with Supabase in Next.js App Router<\/a><\/li>\n\n\n\n<li><a href=\"\/setup-react-query-in-nextjs-13-app-directory\/\">How to Setup React Query in Next.js 13 App Directory<\/a><\/li>\n\n\n\n<li><a href=\"\/react-query-user-registration-and-email-verification\">React Query and Axios: User Registration and Email Verification<\/a><\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"850\" height=\"552\" src=\"https:\/\/codevoweb.com\/wp-content\/uploads\/2025\/03\/How-to-Convert-HTML-to-PDF-in-JavaScript-Example-with-Code.webp\" alt=\"How to Convert HTML to PDF in JavaScript - Example with Code\" class=\"wp-image-12936\" srcset=\"https:\/\/codevoweb.com\/wp-content\/uploads\/2025\/03\/How-to-Convert-HTML-to-PDF-in-JavaScript-Example-with-Code.webp 850w, https:\/\/codevoweb.com\/wp-content\/uploads\/2025\/03\/How-to-Convert-HTML-to-PDF-in-JavaScript-Example-with-Code-300x195.webp 300w, https:\/\/codevoweb.com\/wp-content\/uploads\/2025\/03\/How-to-Convert-HTML-to-PDF-in-JavaScript-Example-with-Code-768x499.webp 768w, https:\/\/codevoweb.com\/wp-content\/uploads\/2025\/03\/How-to-Convert-HTML-to-PDF-in-JavaScript-Example-with-Code-100x65.webp 100w, https:\/\/codevoweb.com\/wp-content\/uploads\/2025\/03\/How-to-Convert-HTML-to-PDF-in-JavaScript-Example-with-Code-693x450.webp 693w\" sizes=\"auto, (max-width: 850px) 100vw, 850px\" \/><\/figure>\n\n\n<style>.kb-table-of-content-nav.kb-table-of-content-id12923_496b3c-39 .kb-table-of-content-wrap{padding-top:var(--global-kb-spacing-sm, 1.5rem);padding-right:var(--global-kb-spacing-sm, 1.5rem);padding-bottom:var(--global-kb-spacing-sm, 1.5rem);padding-left:var(--global-kb-spacing-sm, 1.5rem);border-top:1px solid #abb8c3;border-right:1px solid #abb8c3;border-bottom:1px solid #abb8c3;border-left:1px solid #abb8c3;}.kb-table-of-content-nav.kb-table-of-content-id12923_496b3c-39 .kb-table-of-contents-title-wrap{padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.kb-table-of-content-nav.kb-table-of-content-id12923_496b3c-39 .kb-table-of-contents-title-wrap{color:#ffffff;}.kb-table-of-content-nav.kb-table-of-content-id12923_496b3c-39 .kb-table-of-contents-title{color:#ffffff;font-weight:regular;font-style:normal;}.kb-table-of-content-nav.kb-table-of-content-id12923_496b3c-39 .kb-table-of-content-wrap .kb-table-of-content-list{color:#ffffff;font-weight:regular;font-style:normal;margin-top:var(--global-kb-spacing-sm, 1.5rem);margin-right:0px;margin-bottom:0px;margin-left:0px;}@media all and (max-width: 1024px){.kb-table-of-content-nav.kb-table-of-content-id12923_496b3c-39 .kb-table-of-content-wrap{border-top:1px solid #abb8c3;border-right:1px solid #abb8c3;border-bottom:1px solid #abb8c3;border-left:1px solid #abb8c3;}}@media all and (max-width: 767px){.kb-table-of-content-nav.kb-table-of-content-id12923_496b3c-39 .kb-table-of-content-wrap{border-top:1px solid #abb8c3;border-right:1px solid #abb8c3;border-bottom:1px solid #abb8c3;border-left:1px solid #abb8c3;}}<\/style>\n\n\n<h2 class=\"wp-block-heading\">Why Convert HTML to PDF?<\/h2>\n\n\n\n<p>Converting HTML to PDF is essential for various use cases:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Preserving Content Formatting<\/strong>: PDFs maintain the layout and design of your HTML content.<\/li>\n\n\n\n<li><strong>Sharing and Printing<\/strong>: PDFs are universally accessible and easy to share or print.<\/li>\n\n\n\n<li><strong>Offline Access<\/strong>: Users can save and view PDFs without an internet connection.<\/li>\n\n\n\n<li><strong>Compliance and Documentation<\/strong>: Many industries require documents in PDF format for legal or regulatory purposes.<\/li>\n\n\n\n<li><strong>Improve Data Security:<\/strong> PDFs can be password-protected and restricted from editing, adding an extra layer of security to sensitive documents.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Understanding HTML to PDF Conversion<\/h2>\n\n\n\n<p>Before diving into the code, it&#8217;s important to understand how HTML to PDF conversion works in JavaScript. There are three main approaches:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Client-side conversion<\/strong>: This happens entirely in the browser using JavaScript libraries. It&#8217;s suitable for simple documents and doesn&#8217;t require a server.<\/li>\n\n\n\n<li><strong>Server-side conversion<\/strong>: This uses Node.js or another server-side technology to generate PDFs. It&#8217;s better for complex documents or high-volume processing.<\/li>\n\n\n\n<li><strong>Hybrid approach<\/strong>: This combines client-side and server-side techniques for optimal results.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Popular JavaScript Libraries for HTML to PDF Conversion<\/h2>\n\n\n\n<p>Here are some widely used JavaScript libraries for converting HTML to PDF:<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong><a href=\"https:\/\/www.npmjs.com\/package\/jspdf\" target=\"_blank\" rel=\"noreferrer noopener\">jsPDF<\/a><\/strong>: A lightweight library for generating PDFs.<\/li>\n\n\n\n<li><strong><a href=\"https:\/\/www.npmjs.com\/package\/html2pdf.js\" target=\"_blank\" rel=\"noreferrer noopener\">html2pdf.js<\/a><\/strong>: A wrapper around jsPDF and html2canvas for easy HTML to PDF conversion.<\/li>\n\n\n\n<li><strong><a href=\"https:\/\/www.npmjs.com\/package\/puppeteer\" target=\"_blank\" rel=\"noreferrer noopener\">Puppeteer<\/a><\/strong>: A Node.js library for controlling headless Chrome, ideal for server-side PDF generation.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Step-by-Step Guide to Convert HTML to PDF<\/h2>\n\n\n\n<p>Turning HTML into a PDF doesn\u2019t have to be complicated! In this section, we\u2019ll walk through the process step by step, using different tools to make it quick and easy.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Set Up Your Project<\/h3>\n\n\n\n<p>Let&#8217;s start by setting up a Vite project with vanilla JavaScript. Vite provides a fast development environment and optimized build process.<\/p>\n\n\n\n<p>To set up this project from scratch, follow these steps:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Create a new directory for your project<\/li>\n\n\n\n<li>Open a terminal and navigate to your project directory<\/li>\n\n\n\n<li>Initialize a new Vite project:\n<ul class=\"wp-block-list\">\n<li><strong>pnpm<\/strong><br><code>npm create vite@latest html-to-pdf-converter -- --template vanilla<\/code><\/li>\n\n\n\n<li><strong>npm<\/strong><br><code>npm create vite@latest html-to-pdf-converter -- --template vanilla<\/code><\/li>\n\n\n\n<li><strong>yarn<\/strong><br><code>yarn create vite html-to-pdf-converter --template vanilla<\/code><\/li>\n\n\n\n<li><strong>bun<\/strong><br><code>bun create vite@latest html-to-pdf-converter --template vanilla<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Change into the project directory: <code>cd html-to-pdf-converter<\/code><\/li>\n\n\n\n<li>Install the required dependencies: <code>pnpm install<\/code><br>If you used a different package manager, replace <code>pnpm<\/code> with <code>npm<\/code>, <code>yarn<\/code>, or <code>bun<\/code> as needed.<br><\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Install jsPDF Library<\/h3>\n\n\n\n<p>Install the <code>jspdf<\/code> library using your preferred package manager:<\/p>\n\n\n\n<pre>\n<code class=\"language-shell\">\n# npm\nnpm install jspdf\n# pnpm\npnpm add jspdf\n# yarn\nyarn add jspdf\n# bun\nbun add jspdf\n<\/code>\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Create HTML Content<\/h3>\n\n\n\n<p>Modify the existing <code>index.html<\/code> file in your Vite project to include the content you want to convert to PDF.<\/p>\n\n\n\n<pre>\n<code class=\"language-html\">\n&lt;!DOCTYPE html&gt;\n&lt;html lang=&quot;en&quot;&gt;\n&lt;head&gt;\n  &lt;meta charset=&quot;UTF-8&quot;&gt;\n  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;\n  &lt;title&gt;HTML to PDF&lt;\/title&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n  &lt;h1&gt;Hello, World!&lt;\/h1&gt;\n  &lt;p&gt;This is a sample HTML content to be converted into a PDF.&lt;\/p&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;\n<\/code>\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Convert HTML to PDF Using jsPDF<\/h3>\n\n\n\n<p>Open <code>src\/main.js<\/code> and add the following code to convert the HTML content to PDF.<\/p>\n\n\n\n<pre>\n<code class=\"language-js\">\nimport { jsPDF } from &quot;jspdf&quot;;\n\n\/\/ Create a new jsPDF instance\nconst doc = new jsPDF();\n\n\/\/ Add HTML content to the PDF\ndoc.html(document.body, {\n  callback: function (doc) {\n    \/\/ Save the PDF\n    doc.save(&quot;output.pdf&quot;);\n  },\n  x: 10,\n  y: 10,\n});\n<\/code>\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Customize the PDF Output<\/h3>\n\n\n\n<p>You can customize the PDF by adding margins, fonts, and more:<\/p>\n\n\n\n<pre>\n<code class=\"language-js\">\ndoc.setFontSize(16);\ndoc.text(\"Customized PDF\", 10, 20);\ndoc.setFontSize(12);\ndoc.text(\"This PDF has been customized using jsPDF.\", 10, 30);\n<\/code>\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Using jsPDF with html2canvas<\/h3>\n\n\n\n<p>For more control over the PDF generation process, you can use jsPDF and html2canvas separately. This approach gives you more flexibility but requires more code.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">How It Works<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Use html2canvas to render the HTML element to a canvas<\/li>\n\n\n\n<li>Create a new jsPDF instance<\/li>\n\n\n\n<li>Convert the canvas to an image<\/li>\n\n\n\n<li>Add the image to the PDF<\/li>\n\n\n\n<li>Save or display the PDF<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">Implementation<\/h4>\n\n\n\n<p>Here&#8217;s the core code for converting HTML to PDF using jsPDF with html2canvas:<\/p>\n\n\n\n<pre>\n<code class=\"language-js\">\nimport { jsPDF } from 'jspdf';\nimport html2canvas from 'html2canvas';\n\nasync function generatePDF() {\n  \/\/ Get the HTML element\n  const element = document.getElementById('content-to-convert');\n  \n  try {\n    \/\/ Render the element to a canvas\n    const canvas = await html2canvas(element, {\n      scale: 2,\n      logging: false,\n      useCORS: true\n    });\n    \n    \/\/ Calculate dimensions\n    const imgWidth = 210; \/\/ A4 width in mm\n    const pageHeight = 297; \/\/ A4 height in mm\n    const imgHeight = canvas.height * imgWidth \/ canvas.width;\n    \n    \/\/ Create PDF\n    const pdf = new jsPDF('p', 'mm', 'a4');\n    \n    \/\/ Add image to PDF\n    const imgData = canvas.toDataURL('image\/jpeg', 1.0);\n    pdf.addImage(imgData, 'JPEG', 0, 0, imgWidth, imgHeight);\n    \n    \/\/ Save the PDF\n    pdf.save('document.pdf');\n  } catch (error) {\n    console.error('Error generating PDF:', error);\n  }\n}\n<\/code>\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Alternative Libraries for HTML to PDF Conversion<\/h2>\n\n\n\n<p>While <strong>jsPDF<\/strong> is a great tool for generating PDFs, it has its limitations, especially when dealing with complex layouts and styles. Fortunately, there are other powerful libraries like <strong>html2pdf<\/strong> and <strong>Puppeteer<\/strong> that offer more flexibility and advanced features. <\/p>\n\n\n\n<p>In this section, we\u2019ll explore these alternatives, how they work, and when to use them for the best results.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Using html2pdf.js<\/h3>\n\n\n\n<p>The <strong>html2pdf.js<\/strong> library provides a straightforward way to convert HTML to PDF. It combines html2canvas for rendering and jsPDF for PDF generation.<\/p>\n\n\n\n<pre>\n<code class=\"language-shell\">\n# npm\nnpm install html2pdf.js\n# pnpm\npnpm add html2pdf.js\n# yarn\nyarn add html2pdf.js\n# bun\nbun add html2pdf.js\n<\/code>\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">How It Works<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>The library captures the HTML element using html2canvas<\/li>\n\n\n\n<li>It converts the canvas to an image<\/li>\n\n\n\n<li>It adds the image to a PDF document using jsPDF<\/li>\n\n\n\n<li>It saves or displays the PDF<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">Implementation<\/h4>\n\n\n\n<p>Here&#8217;s the core code for converting HTML to PDF using html2pdf.js:<\/p>\n\n\n\n<p>Example usage:<\/p>\n\n\n\n<pre>\n<code class=\"language-js\">\nimport html2pdf from 'html2pdf.js';\n\nfunction generatePDF() {\n  \/\/ Get the HTML element\n  const element = document.getElementById('content-to-convert');\n  \n  \/\/ Configure options\n  const options = {\n    margin: 10,\n    filename: 'document.pdf',\n    image: { type: 'jpeg', quality: 0.98 },\n    html2canvas: { scale: 2 },\n    jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' }\n  };\n  \n  \/\/ Generate PDF\n  html2pdf().from(element).set(options).save();\n}\n<\/code>\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Key Options Explained<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>margin<\/strong>: Sets the margin around the content in the PDF (in mm)<\/li>\n\n\n\n<li><strong>filename<\/strong>: The name of the downloaded PDF file<\/li>\n\n\n\n<li><strong>image.type<\/strong>: The image format used (jpeg or png)<\/li>\n\n\n\n<li><strong>image.quality<\/strong>: The quality of the image (0-1)<\/li>\n\n\n\n<li><strong>html2canvas.scale<\/strong>: The scaling factor for rendering (higher values improve quality but increase file size)<\/li>\n\n\n\n<li><strong>jsPDF.unit<\/strong>: The measurement unit (mm, cm, in)<\/li>\n\n\n\n<li><strong>jsPDF.format<\/strong>: The paper size (a4, letter, etc.)<\/li>\n\n\n\n<li><strong>jsPDF.orientation<\/strong>: The page orientation (portrait or landscape)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Using Puppeteer<\/h3>\n\n\n\n<p>Puppeteer is a Node.js library that provides a high-level API to control Chrome or Chromium over the DevTools Protocol. It&#8217;s an excellent choice for server-side HTML to PDF conversion because it uses the actual Chrome rendering engine, resulting in high-quality PDFs that accurately match what you see in the browser.<\/p>\n\n\n\n<pre>\n<code class=\"language-shell\">\n# npm\nnpm install puppeteer\n# pnpm\npnpm add puppeteer\n# yarn\nyarn add puppeteer\n# bun\nbun add puppeteer\n<\/code>\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">How It Works<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>The client sends HTML content to a server endpoint<\/li>\n\n\n\n<li>The server uses Puppeteer to launch a headless Chrome instance<\/li>\n\n\n\n<li>Puppeteer loads the HTML content in a virtual browser page<\/li>\n\n\n\n<li>Puppeteer generates a PDF from the page<\/li>\n\n\n\n<li>The server sends the PDF back to the client<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Server Implementation<\/h3>\n\n\n\n<p>First, you need to set up a Node.js server with Express and Puppeteer:<\/p>\n\n\n\n<pre>\n<code class=\"language-shell\">\n# npm\nnpm install express puppeteer\n\n# pnpm\npnpm add express puppeteer\n\n# yarn\nyarn add express puppeteer\n\n# bun\nbun add express puppeteer\n\n<\/code>\n<\/pre>\n\n\n\n<p>Then, create a server file (e.g., <code>server.js<\/code>):<\/p>\n\n\n\n<pre>\n<code class=\"language-js\">\nimport express from 'express';\nimport puppeteer from 'puppeteer';\n\nconst app = express();\n\n\/\/ Parse JSON request bodies (built-in middleware)\napp.use(express.json({ limit: '50mb' }));\n\n\/\/ API endpoint to generate PDF\napp.post('\/api\/generate-pdf', async (req, res) =&gt; {\n  try {\n    const { html } = req.body;\n    if (!html) {\n      return res.status(400).json({ error: 'HTML content is required' });\n    }\n\n    const browser = await puppeteer.launch({\n      headless: 'new',\n      args: ['--no-sandbox', '--disable-setuid-sandbox']\n    });\n\n    const page = await browser.newPage();\n    await page.setContent(html, { waitUntil: 'networkidle0' });\n\n    const pdf = await page.pdf({\n      format: 'A4',\n      printBackground: true,\n      margin: { top: '20mm', right: '20mm', bottom: '20mm', left: '20mm' }\n    });\n\n    await browser.close();\n\n    res.setHeader('Content-Type', 'application\/pdf');\n    res.setHeader('Content-Disposition', 'attachment; filename=document-puppeteer.pdf');\n    res.send(pdf);\n  } catch (error) {\n    console.error('Error generating PDF:', error);\n    res.status(500).json({ error: 'Failed to generate PDF' });\n  }\n});\n\n\/\/ Start the server\nconst PORT = process.env.PORT || 3001;\napp.listen(PORT, () =&gt; {\n  console.log(`Server running on port ${PORT}`);\n});\n<\/code>\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Client Implementation<\/h4>\n\n\n\n<p>On the client side, you need to send the HTML content to the server:<\/p>\n\n\n\n<pre>\n<code class=\"language-js\">\nasync function generatePDFWithPuppeteer() {\n  try {\n    \/\/ Get the HTML content\n    const html = document.getElementById('html-content').value;\n    \n    \/\/ Send the HTML to the server\n    const response = await fetch('\/api\/generate-pdf', {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application\/json',\n      },\n      body: JSON.stringify({ html }),\n    });\n    \n    if (!response.ok) {\n      throw new Error('Failed to generate PDF');\n    }\n    \n    \/\/ Get the PDF as a blob\n    const blob = await response.blob();\n    \n    \/\/ Create a URL for the blob\n    const url = URL.createObjectURL(blob);\n    \n    \/\/ Create a link to download the PDF\n    const a = document.createElement('a');\n    a.href = url;\n    a.download = 'document-puppeteer.pdf';\n    document.body.appendChild(a);\n    a.click();\n    \n    \/\/ Clean up\n    document.body.removeChild(a);\n    URL.revokeObjectURL(url);\n  } catch (error) {\n    console.error('Error generating PDF with Puppeteer:', error);\n    alert('Error generating PDF. Check console for details.');\n  }\n}\n<\/code>\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Advanced Customization Options<\/h2>\n\n\n\n<p>Sometimes, just converting HTML to PDF isn\u2019t enough\u2014you might need more control over the final output. Whether it\u2019s customizing page layouts, adding headers and footers, tweaking margins, or embedding fonts, advanced customization options can make a huge difference. <\/p>\n\n\n\n<p>To keep things concise, this section will focus specifically on jsPDF\u2019s customization features, helping you fine-tune your PDFs with precision.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Custom Fonts<\/h3>\n\n\n\n<p>You can add custom fonts to your PDF using jsPDF:<\/p>\n\n\n\n<pre>\n<code class=\"language-js\">\nimport { jsPDF } from 'jspdf';\n\nfunction addCustomFont() {\n  const pdf = new jsPDF();\n  \n  \/\/ Add a custom font\n  pdf.addFont('fonts\/OpenSans-Regular.ttf', 'OpenSans', 'normal');\n  \n  \/\/ Use the custom font\n  pdf.setFont('OpenSans');\n  pdf.setFontSize(16);\n  pdf.text('This text uses a custom font', 20, 20);\n  \n  pdf.save('custom-font-document.pdf');\n}\n<\/code>\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Page Headers and Footers<\/h3>\n\n\n\n<p>Adding headers and footers to each page:<\/p>\n\n\n\n<pre>\n<code class=\"language-js\">\nfunction addHeadersAndFooters() {\n  const pdf = new jsPDF();\n  const pageCount = 5; \/\/ Example: 5 pages\n  \n  \/\/ Add content to each page\n  for (let i = 1; i &lt;= pageCount; i++) {\n    if (i &gt; 1) pdf.addPage();\n    \n    \/\/ Add header\n    pdf.setFontSize(10);\n    pdf.setTextColor(100, 100, 100);\n    pdf.text('Company Name - Confidential', 105, 10, { align: 'center' });\n    \n    \/\/ Add page content\n    pdf.setFontSize(12);\n    pdf.setTextColor(0, 0, 0);\n    pdf.text(`Page ${i} Content`, 20, 30);\n    \n    \/\/ Add footer\n    pdf.setFontSize(10);\n    pdf.setTextColor(100, 100, 100);\n    pdf.text(`Page ${i} of ${pageCount}`, 105, 287, { align: 'center' });\n  }\n  \n  pdf.save('document-with-headers-footers.pdf');\n}\n<\/code>\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Tables<\/h3>\n\n\n\n<p>For complex tables, you can use jsPDF&#8217;s autoTable plugin:<\/p>\n\n\n\n<pre>\n<code class=\"language-js\">\nimport { jsPDF } from 'jspdf';\nimport 'jspdf-autotable';\n\nfunction generateTablePDF() {\n  const pdf = new jsPDF();\n  \n  \/\/ Define table data\n  const tableData = [\n    ['Name', 'Email', 'Country', 'Age'],\n    ['John Doe', 'john@example.com', 'USA', '38'],\n    ['Jane Smith', 'jane@example.com', 'Canada', '45'],\n    ['Bob Johnson', 'bob@example.com', 'UK', '29'],\n    ['Alice Brown', 'alice@example.com', 'Australia', '32']\n  ];\n  \n  \/\/ Generate table\n  pdf.autoTable({\n    head: [tableData[0]],\n    body: tableData.slice(1),\n    startY: 20,\n    styles: {\n      fontSize: 12,\n      cellPadding: 5,\n      overflow: 'linebreak',\n      halign: 'center'\n    },\n    headStyles: {\n      fillColor: [41, 128, 185],\n      textColor: 255\n    },\n    alternateRowStyles: {\n      fillColor: [240, 240, 240]\n    }\n  });\n  \n  pdf.save('table-document.pdf');\n}\n<\/code>\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">CSS Support<\/h3>\n\n\n\n<p>When using html2canvas, you can include CSS styles in your HTML:<\/p>\n\n\n\n<pre>\n<code class=\"language-js\">\nfunction generateStyledPDF() {\n  \/\/ Create a container with styled content\n  const element = document.createElement('div');\n  element.innerHTML = `\n    &lt;style&gt;\n      .pdf-container {\n        font-family: Arial, sans-serif;\n        padding: 20px;\n      }\n      .pdf-header {\n        color: #2563eb;\n        border-bottom: 2px solid #2563eb;\n        padding-bottom: 10px;\n      }\n      .pdf-content {\n        margin-top: 20px;\n      }\n      .pdf-table {\n        width: 100%;\n        border-collapse: collapse;\n        margin-top: 20px;\n      }\n      .pdf-table th, .pdf-table td {\n        border: 1px solid #ddd;\n        padding: 8px;\n      }\n      .pdf-table th {\n        background-color: #f1f5f9;\n      }\n    &lt;\/style&gt;\n    &lt;div class=&quot;pdf-container&quot;&gt;\n      &lt;h1 class=&quot;pdf-header&quot;&gt;Styled Document&lt;\/h1&gt;\n      &lt;div class=&quot;pdf-content&quot;&gt;\n        &lt;p&gt;This document includes CSS styling that will be captured in the PDF.&lt;\/p&gt;\n        &lt;table class=&quot;pdf-table&quot;&gt;\n          &lt;thead&gt;\n            &lt;tr&gt;\n              &lt;th&gt;Item&lt;\/th&gt;\n              &lt;th&gt;Description&lt;\/th&gt;\n              &lt;th&gt;Price&lt;\/th&gt;\n            &lt;\/tr&gt;\n          &lt;\/thead&gt;\n          &lt;tbody&gt;\n            &lt;tr&gt;\n              &lt;td&gt;Item 1&lt;\/td&gt;\n              &lt;td&gt;Description of item 1&lt;\/td&gt;\n              &lt;td&gt;$100.00&lt;\/td&gt;\n            &lt;\/tr&gt;\n            &lt;tr&gt;\n              &lt;td&gt;Item 2&lt;\/td&gt;\n              &lt;td&gt;Description of item 2&lt;\/td&gt;\n              &lt;td&gt;$150.00&lt;\/td&gt;\n            &lt;\/tr&gt;\n          &lt;\/tbody&gt;\n        &lt;\/table&gt;\n      &lt;\/div&gt;\n    &lt;\/div&gt;\n  `;\n  \n  document.body.appendChild(element);\n  \n  \/\/ Generate PDF with styles\n  html2pdf().from(element).save().then(() =&gt; {\n    document.body.removeChild(element);\n  });\n}\n<\/code>\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Comparing the Three Methods<\/h2>\n\n\n\n<p>Let&#8217;s now compare the three popular tools for converting HTML to PDF: jsPDF, html2pdf, and Puppeteer. This will help you choose the best option for your project.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Feature<\/th><th>html2pdf.js<\/th><th>jsPDF + html2canvas<\/th><th>Puppeteer<\/th><\/tr><\/thead><tbody><tr><td>Environment<\/td><td>Client-side<\/td><td>Client-side<\/td><td>Server-side<\/td><\/tr><tr><td>Setup Complexity<\/td><td>Low<\/td><td>Medium<\/td><td>High<\/td><\/tr><tr><td>Rendering Quality<\/td><td>Good<\/td><td>Good<\/td><td>Excellent<\/td><\/tr><tr><td>CSS Support<\/td><td>Limited<\/td><td>Limited<\/td><td>Full<\/td><\/tr><tr><td>JavaScript Support<\/td><td>Limited<\/td><td>Limited<\/td><td>Full<\/td><\/tr><tr><td>Performance<\/td><td>Depends on browser<\/td><td>Depends on browser<\/td><td>Consistent<\/td><\/tr><tr><td>File Size<\/td><td>Can be large<\/td><td>Can be large<\/td><td>Optimized<\/td><\/tr><tr><td>Best For<\/td><td>Simple documents<\/td><td>Medium complexity<\/td><td>Complex layouts<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>In this guide, we explored three powerful tools for converting HTML to PDF: jsPDF, html2pdf, and Puppeteer. Each method comes with its own strengths\u2014jsPDF is great for client-side PDF generation, html2pdf offers an easy way to convert entire HTML elements, and Puppeteer provides a robust server-side solution for handling complex layouts.<\/p>\n\n\n\n<p>Choosing the right tool depends on your specific needs, whether it&#8217;s generating lightweight PDFs in the browser or creating high-quality documents on the server. As you integrate these solutions into your projects, don\u2019t hesitate to experiment with their customization options to achieve the perfect output.<\/p>\n\n\n\n<p>In upcoming articles, we\u2019ll take a deeper dive into each library, exploring their advanced features and capabilities to help you make the most of them.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A few weeks ago, I ran into a challenge at work\u2014I needed to generate PDFs from dynamically generated HTML content. Whether it was for invoices,&#8230;<\/p>\n","protected":false},"author":1,"featured_media":12936,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[46],"tags":[37],"class_list":["post-12923","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-javascript","tag-javascript"],"acf":[],"_links":{"self":[{"href":"https:\/\/codevoweb.com\/wp-json\/wp\/v2\/posts\/12923","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/codevoweb.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codevoweb.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codevoweb.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/codevoweb.com\/wp-json\/wp\/v2\/comments?post=12923"}],"version-history":[{"count":12,"href":"https:\/\/codevoweb.com\/wp-json\/wp\/v2\/posts\/12923\/revisions"}],"predecessor-version":[{"id":12937,"href":"https:\/\/codevoweb.com\/wp-json\/wp\/v2\/posts\/12923\/revisions\/12937"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/codevoweb.com\/wp-json\/wp\/v2\/media\/12936"}],"wp:attachment":[{"href":"https:\/\/codevoweb.com\/wp-json\/wp\/v2\/media?parent=12923"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codevoweb.com\/wp-json\/wp\/v2\/categories?post=12923"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codevoweb.com\/wp-json\/wp\/v2\/tags?post=12923"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}