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 🙏

© 2026 – Pkg Stats / Ryan Hefner

pdf-catalog-generator

v3.1.4

Published

Generate product catalog PDFs from Excel, CSV, or JSON data

Downloads

181

Readme

PDF Catalog Generator

npm version License: MIT TypeScript

Generate beautiful product catalog PDFs from Excel, CSV, or JSON data with multiple professional templates.

Features

  • 🎨 4 Professional Templates - Choose from multiple layout options
  • 📊 Multiple Input Formats - Excel, CSV, and JSON support
  • 🏢 Customizable Branding - Add your company logo and name
  • 📦 Dual Package - Supports both ESM and CommonJS
  • 🔒 Type Safe - Full TypeScript support with type definitions
  • Tested - Comprehensive unit test coverage
  • 📚 Well Documented - Interactive Storybook documentation

Installation

npm install pdf-catalog-generator

Quick Start

import { generateProductCatalog } from 'pdf-catalog-generator';
import fs from 'fs';

const pdfBuffer = await generateProductCatalog({
  products: [
    {
      Title: 'Laptop Pro 15',
      Description: 'High-performance laptop',
      Image: 'https://example.com/laptop.jpg',
      Price: 1299.99,
      Rating: 4.5,
      Link: 'https://store.example.com/laptop'
    }
  ],
  companyName: 'Tech Store',
  companyLogo: 'https://example.com/logo.png',
  template: 'template1'
});

// Save to file
fs.writeFileSync('catalog.pdf', pdfBuffer);

Platform Compatibility

This library works seamlessly across different JavaScript environments:

  • Node.js - Backend servers, build scripts, CLI tools
  • Browser/React - Client-side web applications
  • Next.js - Both server components (SSR) and client components

Browser/React Usage

import { parseExcelFile, generateProductCatalog } from 'pdf-catalog-generator';

async function handleFileUpload(event: React.ChangeEvent<HTMLInputElement>) {
  const file = event.target.files?.[0];
  if (!file) return;

  // Use browser File API
  const arrayBuffer = await file.arrayBuffer();

  // Parse with ArrayBuffer (cross-platform compatible)
  const products = parseExcelFile(arrayBuffer);

  // Generate PDF
  const pdfBuffer = await generateProductCatalog({
    products,
    companyName: 'My Store',
    template: 'template1',
  });

  // Download in browser
  const blob = new Blob([pdfBuffer], { type: 'application/pdf' });
  const url = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = url;
  link.download = 'catalog.pdf';
  link.click();
  URL.revokeObjectURL(url);
}

Next.js Usage

Server Component (App Router):

// app/api/generate-catalog/route.ts
import { parseExcelFile, generateProductCatalog } from 'pdf-catalog-generator';

export async function POST(request: Request) {
  const formData = await request.formData();
  const file = formData.get('file') as File;

  // Convert File to ArrayBuffer
  const arrayBuffer = await file.arrayBuffer();

  const products = parseExcelFile(arrayBuffer);
  const pdfBuffer = await generateProductCatalog({
    products,
    companyName: 'My Store',
  });

  return new Response(pdfBuffer, {
    headers: {
      'Content-Type': 'application/pdf',
      'Content-Disposition': 'attachment; filename="catalog.pdf"',
    },
  });
}

Client Component:

'use client';

import { useState } from 'react';
import { parseExcelFile, generateProductCatalog } from 'pdf-catalog-generator';

export default function CatalogGenerator() {
  const handleGenerate = async (file: File) => {
    const arrayBuffer = await file.arrayBuffer();
    const products = parseExcelFile(arrayBuffer);
    const pdfBuffer = await generateProductCatalog({
      products,
      companyName: 'My Store',
    });

    // Download
    const blob = new Blob([pdfBuffer], { type: 'application/pdf' });
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = 'catalog.pdf';
    link.click();
  };

  return (
    <input
      type="file"
      accept=".xlsx,.csv"
      onChange={(e) => e.target.files?.[0] && handleGenerate(e.target.files[0])}
    />
  );
}

Input Types

The parser functions accept multiple input types for cross-platform compatibility:

  • Node.js Buffer - fs.readFileSync() returns Buffer
  • ArrayBuffer - Browser File.arrayBuffer() returns ArrayBuffer
  • Uint8Array - Universal typed array format

All input types are automatically detected and handled correctly.

API Reference

generateProductCatalog(config)

Generates a PDF catalog from the provided configuration.

Parameters:

  • config (CatalogConfig):
    • products (ProductData[]): Array of product data
    • companyName (string): Your company name
    • companyLogo (string | null, optional): Logo URL or base64 string
    • template (TemplateType, optional): Template to use (default: 'template1')
    • imageOptimization (ImageOptimizationOptions, optional): Resize/compress supported remote image URLs before rendering. Enabled by default.

Returns: Promise<Uint8Array> - PDF file as Uint8Array (works in both Node.js and browser)

parseExcelFile(buffer)

Parse Excel file buffer into product data.

Parameters:

  • buffer (Buffer | ArrayBuffer | Uint8Array): Excel file data
    • Node.js: Use Buffer from fs.readFileSync()
    • Browser: Use ArrayBuffer from file.arrayBuffer()
    • Universal: Uint8Array works everywhere

Returns: ProductData[] - Array of products

Example (Node.js):

import { parseExcelFile, generateProductCatalog } from 'pdf-catalog-generator';
import fs from 'fs';

const excelBuffer = fs.readFileSync('products.xlsx');
const products = parseExcelFile(excelBuffer);
const pdfBuffer = await generateProductCatalog({
  products,
  companyName: 'My Store'
});

Example (Browser/React):

import { parseExcelFile, generateProductCatalog } from 'pdf-catalog-generator';

const file = event.target.files[0];
const arrayBuffer = await file.arrayBuffer();
const products = parseExcelFile(arrayBuffer);
const pdfBuffer = await generateProductCatalog({
  products,
  companyName: 'My Store'
});

parseCSVFile(csvString)

Parse CSV string into product data.

Parameters:

  • csvString (string): CSV content as string

Returns: ProductData[] - Array of products

Example:

import { parseCSVFile, generateProductCatalog } from 'pdf-catalog-generator';
import fs from 'fs';

const csvString = fs.readFileSync('products.csv', 'utf-8');
const products = parseCSVFile(csvString);
const pdfBuffer = await generateProductCatalog({
  products,
  companyName: 'My Store'
});

parseCSVBuffer(buffer)

Parse CSV buffer into product data.

Parameters:

  • buffer (Buffer | ArrayBuffer | Uint8Array): CSV file data
    • Node.js: Use Buffer from fs.readFileSync()
    • Browser: Use ArrayBuffer from file.arrayBuffer()
    • Universal: Uint8Array works everywhere

Returns: ProductData[] - Array of products

parseJSON(data)

Parse JSON product data. No fields are mandatory - data is passed through as-is.

Parameters:

  • data (any[]): Array of product objects

Returns: ProductData[] - Products passed through without modification

Note: parseJSON no longer validates or normalizes data. It simply passes through your data as-is, just like the Excel/CSV parsers.

Example:

import { parseJSON, generateProductCatalog } from 'pdf-catalog-generator';

const rawData = [
  { Title: 'Product 1', Link: 'https://example.com/1' },
  { sku: 'ABC-123', name: 'Custom Product', color: 'Blue' },
  { designNumber: 'DN-001', fabric: 'Cotton', gsm: 180 }
];

const products = parseJSON(rawData); // All pass through without modification
const pdfBuffer = await generateProductCatalog({
  products,
  companyName: 'My Store'
});

Data Format

ProductData

This library is completely schema-free - no fields are mandatory! You can use any data structure you want.

interface ProductData {
  [key: string]: string | number | boolean | null | undefined;
}

interface ImageOptimizationOptions {
  enabled?: boolean;
  maxWidth?: number;
  maxHeight?: number;
  quality?: number;
  logoMaxWidth?: number;
  logoMaxHeight?: number;
  logoQuality?: number;
}

Dynamic Field Rendering:

  • All templates automatically detect and display whatever fields you provide
  • Common fields (Title, Description, Image, Price, Rating, Link) are displayed prominently if present
  • All other fields are rendered dynamically with auto-formatted labels
  • Missing fields are gracefully handled - nothing breaks!

Common Field Names (Optional): Templates intelligently look for these common fields (case-insensitive):

  • Title/Name/ProductName - Displayed as main heading
  • Image/ImageUrl/photo - Used as product image (fallback image if missing)
  • Description/Details/Info - Shown as product description
  • Price/Cost/Amount - Displayed prominently (formatted if provided)
  • Rating/Stars/Score - Shown with star emoji if present
  • Link/URL/ProductUrl - Powers "Buy Now" buttons

Custom Fields: Any other fields are automatically displayed with smart formatting:

  • designNumber → "Design Number"
  • gsm → "GSM" (uppercase for known acronyms)
  • fabric_finish → "Fabric Finish"

Example - Traditional E-commerce:

{
  Title: 'Laptop Pro 15',
  Description: 'High-performance laptop',
  Image: 'https://example.com/laptop.jpg',
  Price: 1299.99,
  Rating: 4.5,
  Link: 'https://store.example.com/laptop'
}

Example - Custom Textile Catalog:

{
  designNumber: 'DN-12345',
  fabric: '100% Cotton',
  gsm: 180,
  finish: 'Mercerized',
  color: 'Navy Blue',
  Image: 'https://example.com/fabric.jpg'
}

Example - Minimal:

{
  name: 'Widget',
  sku: 'WDG-001'
}

All of the above work perfectly! Templates adapt to your data structure.

Templates

All templates are fully dynamic and adapt to your data structure. They intelligently detect common fields and display all additional fields automatically.

Template 1: Grid Layout

2-column grid layout with product cards. Perfect for showcasing multiple products.

template: 'template1'

Best for: Products with mixed field types - automatically displays all fields in a compact grid card.

Template 2: List Layout

Full-width horizontal layout with image on left, details on right. Great for detailed product information.

template: 'template2'

Best for: Detailed products - shows all fields with room for descriptions and custom attributes.

Template 3: Full Page Layout

Full-page product view with image background and overlay details box. One product per page.

template: 'template3'

Best for: Premium catalogs with hero images - displays key fields in an elegant overlay box (shows up to 5 custom fields).

Template 4: One-Per-Page

Full-page product view with header on each page and all product details listed. One product per page.

template: 'template4'

Best for: Maximum detail - displays ALL product fields with formatted labels. Ideal for technical specifications or textile catalogs.

TypeScript Support

This package is written in TypeScript and includes type definitions:

import type { CatalogConfig, ProductData, TemplateType } from 'pdf-catalog-generator';

const config: CatalogConfig = {
  products: [],
  companyName: 'My Company',
  template: 'template1'
};

Examples

Check the examples/ directory for complete working examples:

  • Basic usage
  • Excel to PDF
  • CSV to PDF
  • Custom templates

Development

# Install dependencies
npm install

# Run tests
npm test

# Run tests with coverage
npm run test:coverage

# Build package
npm run build

# Run Storybook
npm run storybook

# Lint code
npm run lint

# Format code
npm run format

Contributing

Contributions are welcome! Please read CONTRIBUTING.md for details on our code of conduct and the process for submitting pull requests.

Changelog

See CHANGELOG.md for a list of changes.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

Credits

Built with: