html-to-files
v0.0.2
Published
A simple utility to convert HTML content (with optional header and footer) to PDF buffer using wkhtmltopdf.
Maintainers
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 ([email protected])
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 | [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 forwkhtmltopdf.extraOptions:string(optional)
Extra options forwkhtmltopdf.
Returns
buffer:Buffer
The generated PDF as a buffer.mimetype:string
Always"application/pdf".
