npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

html-to-files

v0.0.2

Published

A simple utility to convert HTML content (with optional header and footer) to PDF buffer using wkhtmltopdf.

Readme

html-to-files

A simple and powerful utility to convert HTML content (with optional header and footer) to PDF buffer using wkhtmltopdf.

Features

  • ✅ Convert HTML content to PDF buffer
  • ✅ Support for custom headers and footers
  • ✅ Flexible wkhtmltopdf options
  • ✅ TypeScript support
  • ✅ Temporary file management
  • ✅ Cross-platform compatibility

Installation

npm install html-to-files

Prerequisites

This package requires wkhtmltopdf to be installed on your system:

Ubuntu/Debian:

sudo apt-get install wkhtmltopdf

macOS:

brew install wkhtmltopdf

Windows: Download from wkhtmltopdf.org

Usage

Basic Example

const { htmlToPdf } = require('html-to-files');

const htmlContent = {
  content: '<h1>Hello World</h1><p>This is a PDF generated from HTML!</p>'
};

const pdfData = await htmlToPdf({ htmlContent });
console.log('PDF generated with size:', pdfData.buffer.byteLength);

Advanced Example with Header and Footer

const { htmlToPdf } = require('html-to-files');

const htmlContent = {
  header: '<div style="text-align: center; font-size: 12px;">Document Header</div>',
  footer: '<div style="text-align: center; font-size: 10px;">Page <span class="page"></span> of <span class="topage"></span></div>',
  content: `
    <html>
      <head>
        <style>
          body { font-family: Arial, sans-serif; margin: 20px; }
          h1 { color: #333; }
        </style>
      </head>
      <body>
        <h1>My Document</h1>
        <p>This is the main content of the document.</p>
      </body>
    </html>
  `
};

const pdfData = await htmlToPdf({
  htmlContent,
  id: 'my-document',
  extraOptions: '--page-size A4 --margin-top 20mm --margin-bottom 20mm'
});

// Save to file or send as response
require('fs').writeFileSync('output.pdf', pdfData.buffer);

Integration with EJS Templates

Here's how you can use this package with EJS for dynamic content generation:

const { htmlToPdf } = require('html-to-files');
const ejs = require('ejs');

/**
 * Generate a PDF from given templates using EJS for dynamic content
 *
 * @param {Object} options - Templates and settings
 * @param {string} options.footerTemplate - Footer HTML string
 * @param {boolean} options.footerEnable - Whether footer should be included
 * @param {string} options.headerTemplate - Header HTML string
 * @param {boolean} options.headerEnable - Whether header should be included
 * @param {string} options.bodyTemplate   - Body HTML string (required)
 * @param {Object} data - Data to replace in templates
 * @param {Object} data.footerData - Data for footer EJS
 * @param {Object} data.headerData - Data for header EJS
 * @param {Object} data.bodyData   - Data for body EJS
 * @param {string} id - Unique ID for temp files
 * @param {string} [extraOptions] - wkhtmltopdf options
 */
exports.toPdfHandler = async (
  { 
    footerTemplate = "", 
    footerEnable = false, 
    headerTemplate = "", 
    headerEnable = false, 
    bodyTemplate 
  },
  { 
    footerData = {}, 
    headerData = {}, 
    bodyData = {} 
  } = {},
  id = "pdf-temp",
  extraOptions = "--disable-smart-shrinking --page-size A4 --margin-bottom 15"
) => {
  try {
    // ✅ Render templates with EJS if data provided
    const renderedContent = ejs.render(bodyTemplate, bodyData);
    const htmlContent = {
      content: renderedContent,
    };

    if (footerEnable && footerTemplate) {
      htmlContent.footer = ejs.render(footerTemplate, footerData);
    }

    if (headerEnable && headerTemplate) {
      htmlContent.header = ejs.render(headerTemplate, headerData);
    }

    // ✅ Generate PDF using html-to-files
    const pdfData = await htmlToPdf({
      htmlContent,
      extraOptions,
      id, // unique temp ID
    });

    return pdfData.buffer; // Return PDF buffer
  } catch (error) {
    console.error("PDF generation failed:", error);
    throw error;
  }
};

API Reference

htmlToPdf(params)

Converts HTML content to PDF buffer.

Parameters

  • params (Object)
    • htmlContent (Object) - Required
      • content (string) - Required - Main HTML content
      • header (string) - Optional header HTML
      • footer (string) - Optional footer HTML
    • id (string) - Optional unique identifier for temporary files (auto-generated if not provided)
    • commandParts (string[]) - Optional custom wkhtmltopdf command parts
    • extraOptions (string) - Optional additional wkhtmltopdf options

Returns

Promise that resolves to:

{
  buffer: Buffer,     // PDF file as Buffer
  mimetype: string    // Always "application/pdf"
}

Example Options

// Common wkhtmltopdf options
const extraOptions = [
  '--page-size A4',
  '--margin-top 20mm',
  '--margin-bottom 20mm',
  '--margin-left 15mm',
  '--margin-right 15mm',
  '--disable-smart-shrinking',
  '--print-media-type'
].join(' ');

Error Handling

try {
  const pdfData = await htmlToPdf({ htmlContent });
  console.log('Success:', pdfData.buffer.byteLength, 'bytes');
} catch (error) {
  console.error('PDF generation failed:', error.message);
  // Handle error appropriately
}

TypeScript Support

This package includes TypeScript definitions:

import { htmlToPdf } from 'html-to-files';

interface HtmlContent {
  header?: string;
  footer?: string;
  content: string;
}

interface PdfParams {
  id?: string;
  htmlContent: HtmlContent;
  commandParts?: string[];
  extraOptions?: string;
}

const result = await htmlToPdf({
  htmlContent: {
    content: '<h1>TypeScript Example</h1>'
  }
});

Common Use Cases

Express.js Integration

const express = require('express');
const { htmlToPdf } = require('html-to-files');

app.get('/generate-pdf', async (req, res) => {
  try {
    const htmlContent = {
      content: '<h1>Generated Report</h1><p>Report content here...</p>'
    };
    
    const pdfData = await htmlToPdf({ htmlContent });
    
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', 'attachment; filename="report.pdf"');
    res.send(pdfData.buffer);
  } catch (error) {
    res.status(500).json({ error: 'PDF generation failed' });
  }
});

Batch Processing

const documents = [
  { id: 'doc1', content: '<h1>Document 1</h1>' },
  { id: 'doc2', content: '<h1>Document 2</h1>' }
];

const pdfs = await Promise.all(
  documents.map(doc => 
    htmlToPdf({
      htmlContent: { content: doc.content },
      id: doc.id
    })
  )
);

Troubleshooting

Common Issues

  1. wkhtmltopdf not found: Ensure wkhtmltopdf is installed and in your PATH
  2. Permission errors: Check file system permissions for temporary directory
  3. Large files: For large HTML content, consider increasing Node.js memory limit

Debug Mode

Enable debug logging by setting the environment variable:

DEBUG=html-to-files node your-app.js

License

MIT

Author

Karmur Ramesh ([email protected])

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Changelog

v0.0.2

  • Initial release
  • Basic HTML to PDF conversion
  • Header and footer support
  • TypeScript definitions

A simple utility to convert HTML content (with optional header and footer) to a PDF buffer using wkhtmltopdf.

Features

  • Convert HTML content to PDF buffer
  • Supports custom header and footer HTML
  • Cleans up all temporary files automatically

Installation

npm install html-to-files

Note:
This package requires wkhtmltopdf to be installed and available in your system's PATH.

Usage

TypeScript

import { htmlToPdf } from "html-to-files";

async function generatePdf() {
	const headerHtml = `
<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <style>
      body {
        font-family: "Montserrat", sans-serif;
        font-size: 12px;
        margin: 0;
        padding: 0;
        color: #000000;
      }
      .header {
        width: 100%;
        padding: 10px 0;
        border-bottom: 1px solid #125084;
        display: table;
        table-layout: fixed;
      }
      .logo,
      .contact {
        display: table-cell;
        vertical-align: middle;
      }
      .logo {
        width: 50%;
      }
      .logo img {
        height: 50px;
        max-width: 100%;
        vertical-align: middle;
      }
      .contact {
        width: 50%;
        text-align: right;
        font-size: 12px;
      }
    </style>
  </head>
  <body>
    <div class="header">
      <div class="logo">
        <img src="" alt="Logo" />
      </div>
      <div class="contact">
        <div>+1 234 567 890 | [email protected]</div>
        <div>123 Main St, City, Country</div>
      </div>
    </div>
  </body>
</html>
`;

	const footerHtml = `
<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <style>
      body {
        font-family: 'Montserrat', sans-serif;
        font-size: 10px;
        margin: 0;
        padding: 0;
        color: #000000;
      }
      .footer {
        width: 100%;
        text-align: center;
        border-top: 1px solid #ccc;
        padding-top: 5px;
      }
    </style>
    <script>
      var pdfInfo = {};
      var x = document.location.search.substring(1).split('&');
      for (var i in x) {
        var z = x[i].split('=', 2);
        pdfInfo[z[0]] = unescape(z[1]);
      }
      function getPdfInfo() {
        var page = pdfInfo.page || 1;
        var pageCount = pdfInfo.topage || 1;
        document.getElementById('pdfkit_page_current').textContent = page;
        // document.getElementById('pdfkit_page_count').textContent = pageCount;
      }
      window.onload = getPdfInfo;
    </script>
  </head>
  <body>
    <div class="footer">
      PRICES LISTED REFLECT A CASH DISCOUNT OF 3%. CREDIT CARDS ARE ACCEPTED WITH A NON CASH ADJUSTMENT
      <p style="margin: 5px 0; color: #888;">
        Page <span id="pdfkit_page_current"></span>
      </p>
    </div>
  </body>
</html>
`;

	const contentHtml = `
<!doctype html>
<html>
<head>
  <meta charset="UTF-8" />
  <style>
    @page {
      margin: 20mm;
    }

    body {
      font-family: "Montserrat", sans-serif;
      font-size: 12px;
      margin: 0;
      padding: 10px;
      color: #000000;
    }

    .title {
      text-align: center;
      font-size: 18px;
      font-weight: bold;
      margin-bottom: 20px;
    }

    table {
      width: 100%;
      border-collapse: collapse;
      margin-top: 10px;
      page-break-inside: auto;
    }

    tr {
      page-break-inside: avoid;
      page-break-after: auto;
    }

    th, td {
      border: 1px solid #ccc;
      padding: 8px;
      text-align: left;
    }

    th {
      background-color: #f3f3f3;
    }
  </style>
</head>
<body>
  <div class="title">Estimate Summary</div>
  <table>
    <thead>
      <tr>
        <th>Item</th>
        <th>Description</th>
        <th>Quantity</th>
        <th>Rate</th>
        <th>Total</th>
      </tr>
    </thead>
    <tbody>
      ${Array.from({ length: 60 })
			.map(
				(_, i) =>
					`<tr>
        				<td>${i + 1}</td>
        				<td>Boat Repair</td>
        				<td>2</td>
        				<td>$150</td>
        				<td>$300</td>
      				</tr>`
			)
			.join("")}
     
      <tr>
        <td colspan="4" style="text-align: right;"><strong>Grand Total</strong></td>
        <td><strong>$750</strong></td>
      </tr>
    </tbody>
  </table>
</body>
</html>
`;
	const id = "123456"; // Replace with your dynamic ID

	const pdfData = await htmlToPdf({
		htmlContent: {
			content: bodyHtml,
			header: headerHtml,
			footer: footerHtml,
		},
		commandParts: ["wkhtmltopdf"], // Optional: custom command parts
		extraOptions: "--disable-smart-shrinking --page-size A4 --margin-bottom 15", // Optional: extra wkhtmltopdf options
		id: id, // Optional: unique ID for temp files
	});

	console.log("PDF Buffer Length:", pdfData.buffer.length);
	// Use pdfData.buffer as needed (e.g., save to file, send as response)
}

generatePdf().catch(console.error);

JavaScript

const { htmlToPdf } = require("html-to-files");

async function generatePdf() {
	const id = "123456"; // Replace with your dynamic ID

	const pdfData = await htmlToPdf({
		htmlContent: {
			content: bodyHtml,
			header: headerHtml,
			footer: footerHtml,
		},
		commandParts: ["wkhtmltopdf"], // Optional: custom command parts
		extraOptions: "--disable-smart-shrinking --page-size A4 --margin-bottom 15", // Optional: extra wkhtmltopdf options
		id: id, // Optional: unique ID for temp files
	});

	console.log("PDF Buffer Length:", pdfData.buffer.length);
	// Use pdfData.buffer as needed (e.g., save to file, send as response)
}

generatePdf().catch(console.error);

API

bufferPdf(params: PdfParams): Promise<{ buffer: Buffer; mimetype: string }>

Parameters

  • htmlContent: { content: string; header?: string; footer?: string }
    The main HTML content and optional header/footer HTML.
  • commandParts: string[] (optional)
    Custom command parts for wkhtmltopdf.
  • extraOptions: string (optional)
    Extra options for wkhtmltopdf.

Returns

  • buffer: Buffer
    The generated PDF as a buffer.
  • mimetype: string
    Always "application/pdf".