Package Exports
- html-to-files
- html-to-files/build/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (html-to-files) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
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-filesPrerequisites
This package requires wkhtmltopdf to be installed on your system:
Ubuntu/Debian:
sudo apt-get install wkhtmltopdfmacOS:
brew install wkhtmltopdfWindows: 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) - Requiredcontent(string) - Required - Main HTML contentheader(string) - Optional header HTMLfooter(string) - Optional footer HTML
id(string) - Optional unique identifier for temporary files (auto-generated if not provided)commandParts(string[]) - Optional custom wkhtmltopdf command partsextraOptions(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
- wkhtmltopdf not found: Ensure wkhtmltopdf is installed and in your PATH
- Permission errors: Check file system permissions for temporary directory
- 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.jsLicense
MIT
Author
Karmur Ramesh (ramesh3dpl@gmail.com)
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - 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-filesNote:
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 | info@example.com</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 forwkhtmltopdf.extraOptions:string(optional)
Extra options forwkhtmltopdf.
Returns
buffer:Buffer
The generated PDF as a buffer.mimetype:string
Always"application/pdf".