search
  • Sign In
  • Sign Up
Password reset successful

Follow the proiects vou are interested in andi aet the latestnews about them taster

Table of Contents
✅ Recommended solution: Puppeteer Express pre-rendering interface
⚠️Key Notes
Home Web Front-end HTML Tutorial How to render HTML on the backend and generate a PDF file

How to render HTML on the backend and generate a PDF file

Jan 03, 2026 pm 05:24 PM

How to render HTML on the backend and generate a PDF file

This article describes how to dynamically render HTML pages and generate high-quality PDFs through a headless browser (such as Puppeteer) on the Node.js backend, which is suitable for automated archiving scenarios of user-customized documents.

When building SaaS or enterprise-level applications, it is often necessary to generate personalized documents (such as contracts, reports, invoices) for each user. The front-end uses React to dynamically fill in data and support printing; however, front-end printing alone cannot meet the needs of automatic archiving, auditing, or asynchronous processing on the server side. At this time, the closed loop of HTML rendering and PDF generation must be completed on the backend - and "running React" directly on the server is not feasible (React is a client-side framework that relies on the DOM and browser environment). The correct path is: the server provides a pre-rendered HTML interface (SSR or static routing) that can be accessed by the browser, and then the headless browser accesses the URL and screenshots/exports it as PDF .

First, ensure that the backend exposes an HTTP interface that returns user-specific HTML (for example, /api/docs/:id/pdf). The interface should:

  • Query user data based on request parameters (such as userId or docId);
  • Use a template engine (such as EJS, Handlebars) or pure string concatenation to generate complete HTML (including inline CSS to avoid external resource loading failure);
  • Return standard HTML response (Content-Type: text/html) to ensure complete style and controllable layout.

Example Express route:

 app.get('/api/docs/:id/pdf', async (req, res) => {
  const { id } = req.params;
  const user = await db.getUser(id); // Replace with your data source const html = `
    
    
      
        <meta charset="UTF-8">
        <style>
          body { font-family: sans-serif; margin: 2cm; }
          .header { color: #2c3e50; text-align: center; }
        </style>
      
      
        <div class="header"><h1>User Agreement</h1></div>
        <p><strong>Name:</strong>${user.name}</p>
        <p><strong>Email:</strong>${user.email}</p>
        <p><strong>Signing date:</strong>${new Date().toLocaleDateString()}</p>
      
    
  `;
  res.send(html);
});

Next, use Puppeteer to access the URL and generate the PDF:

 const puppeteer = require('puppeteer');

async function generatePdfFromUrl(url, options = {}) {
  const browser = await puppeteer.launch({
    headless: true,
    args: ['--no-sandbox', '--disable-setuid-sandbox']
  });
  try {
    const page = await browser.newPage();
    //Set the viewport to match A4 size (ensures accurate layout)
    await page.setViewport({ width: 1200, height: 800 });
    await page.goto(url, { waitUntil: 'networkidle0', timeout: 30000 });

    const pdfBuffer = await page.pdf({
      format: 'A4',
      printBackground: true,
      margin: { top: '20px', right: '20px', bottom: '20px', left: '20px' },
      ...options
    });

    return pdfBuffer;
  } finally {
    await browser.close();
  }
}

// Call the example (such as saving to the file system)
const pdf = await generatePdfFromUrl('http://localhost:3000/api/docs/123/pdf');
require('fs').writeFileSync('./output/user-123.pdf', pdf);

⚠️Key Notes

  • CSS and fonts : PDF export does not support all CSS (for example, flexbox renders abnormally in some versions). It is recommended to use semantic HTML stable CSS (such as float, inline-block or table layout); fonts need to be loaded (@font-face can be inline or system safe fonts can be used).
  • Resource loading : Avoid referencing external CDN resources (such as unproxied Google Fonts), otherwise the headless browser may fail due to network policies; it is recommended to convert fonts and images to base64 inline.
  • Performance and concurrency : Puppeteer instances are heavy, so the production environment must reuse browser instances (use puppeteer.launch({ headless: true }) single instance browser.newPage() for multi-page reuse), or use connection pool management.
  • Security : Never spell user input directly into HTML without escaping to prevent XSS; use DOMPurify.sanitize() or the template engine's automatic escaping mechanism.
  • Weighing alternatives : If the document structure is simple and does not require JavaScript interaction, you can consider pdfmake or html-pdf (based on PhantomJS, no longer maintained), but Puppeteer is currently the most stable and compatible choice.

Through the above method, you can not only maintain the interactive experience of front-end React, but also reliably generate, store and manage user-specific PDF documents on the back-end, truly realizing the separation of responsibilities and complementary capabilities of the front-end and back-end.

The above is the detailed content of How to render HTML on the backend and generate a PDF file. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

ArtGPT

ArtGPT

AI image generator for creative art from text prompts.

Stock Market GPT

Stock Market GPT

AI powered investment research for smarter decisions

Popular tool

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Solve the problem of unexpected offset of Flex container due to the font size change of the first child element Solve the problem of unexpected offset of Flex container due to the font size change of the first child element Mar 09, 2026 pm 08:15 PM

When the first child element of a Flex container dynamically adjusts the font-size, the container will be vertically offset along the inline baseline; while a normal block-level container will change in height due to the linkage between line height and font measurement. The root cause lies in the baseline alignment mechanism of the Flex container. By default, the baseline of the first child is the container baseline. This can be completely solved through vertical-align: top or explicit baseline control.

Chart.js complete implementation solution for dynamically switching chart types (line chart, bar chart, pie chart) Chart.js complete implementation solution for dynamically switching chart types (line chart, bar chart, pie chart) Mar 12, 2026 pm 08:51 PM

This article explains in detail how to safely and reliably dynamically switch chart types (line/bar/pie) in Chart.js, and solve the problem of Cannot read properties of undefined errors caused by mismatched data structures and rendering exceptions after type switching. The core lies in destroying old instances, deep copying configurations, and accurately rebuilding data structures by type.

How to dynamically pass HTML form data to analytics.track() method How to dynamically pass HTML form data to analytics.track() method Mar 13, 2026 pm 10:57 PM

This article explains in detail how to safely and efficiently extract user input from HTML forms and structure it into JavaScript objects as attribute parameters of analytics.track() to avoid hard coding and syntax errors and support flexible expansion.

How to optimize Lighthouse image scoring while maintaining high image quality How to optimize Lighthouse image scoring while maintaining high image quality Mar 11, 2026 pm 09:39 PM

This article explores why providing 2x images to high DPR devices may lower Lighthouse performance scores, and provides practical solutions to balance visual quality and real performance: including proper srcset configuration, image compression strategies, modern format selection, and load priority control.

A complete guide to using the keyboard to control the smooth movement of HTML elements A complete guide to using the keyboard to control the smooth movement of HTML elements Mar 13, 2026 pm 10:18 PM

This article explains in detail why transform: translate() combined with the keydown event cannot move elements, and provides a reliable solution based on CSS positioning and JavaScript, covering absolute positioning settings, coordinate update logic, code robustness optimization, and common pitfalls.

How to properly override default styles and implement custom CSS layouts in Divi theme builder How to properly override default styles and implement custom CSS layouts in Divi theme builder Mar 14, 2026 am 12:00 AM

This article explains in detail the root cause of style failure when applying custom CSS in the WordPress Divi theme builder. It provides practical solutions for improving selector specificity, accurately positioning elements, and rational use of !important, as well as debugging tips and code optimization examples.

How to add prompt copy for disabled button click How to add prompt copy for disabled button click Mar 30, 2026 pm 04:30 PM

This article introduces a complete solution for disabling the "Next" button when the form does not meet the conditions, and using native HTML5 form validation or JavaScript dynamic control to display a friendly prompt message when the disabled button is clicked.

How to switch images by clicking a button (elegant implementation based on jQuery) How to switch images by clicking a button (elegant implementation based on jQuery) Apr 04, 2026 pm 08:06 PM

This article introduces how to use jQuery to dynamically switch background images after button clicks, and corrects problems such as CSS selector misuse, inline event coupling, and logical redundancy in the original code, providing a concise and maintainable interaction solution.

Related articles