pdf-catalog-generator 1.1.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,20 @@
1
1
  # PDF Catalog Generator
2
2
 
3
- Generate beautiful product catalog PDFs from Excel, CSV, or JSON data.
3
+ [![npm version](https://img.shields.io/npm/v/pdf-catalog-generator.svg)](https://www.npmjs.com/package/pdf-catalog-generator)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue.svg)](https://www.typescriptlang.org/)
6
+
7
+ Generate beautiful product catalog PDFs from Excel, CSV, or JSON data with multiple professional templates.
8
+
9
+ ## Features
10
+
11
+ - 🎨 **4 Professional Templates** - Choose from multiple layout options
12
+ - 📊 **Multiple Input Formats** - Excel, CSV, and JSON support
13
+ - 🏢 **Customizable Branding** - Add your company logo and name
14
+ - 📦 **Dual Package** - Supports both ESM and CommonJS
15
+ - 🔒 **Type Safe** - Full TypeScript support with type definitions
16
+ - ✅ **Tested** - Comprehensive unit test coverage
17
+ - 📚 **Well Documented** - Interactive Storybook documentation
4
18
 
5
19
  ## Installation
6
20
 
@@ -8,64 +22,439 @@ Generate beautiful product catalog PDFs from Excel, CSV, or JSON data.
8
22
  npm install pdf-catalog-generator
9
23
  ```
10
24
 
11
- ## Usage
25
+ ## Quick Start
12
26
 
13
27
  ```typescript
14
28
  import { generateProductCatalog } from 'pdf-catalog-generator';
29
+ import fs from 'fs';
15
30
 
16
- // From JSON
17
31
  const pdfBuffer = await generateProductCatalog({
18
32
  products: [
19
33
  {
20
- Title: 'Product 1',
21
- Description: 'Description here',
22
- Image: 'https://example.com/image.jpg',
23
- Price: 99.99,
34
+ Title: 'Laptop Pro 15',
35
+ Description: 'High-performance laptop',
36
+ Image: 'https://example.com/laptop.jpg',
37
+ Price: 1299.99,
24
38
  Rating: 4.5,
25
- Link: 'https://example.com/product'
39
+ Link: 'https://store.example.com/laptop'
26
40
  }
27
41
  ],
28
- companyLogo: 'https://example.com/logo.png', // or base64
29
- companyName: 'Your Company',
30
- template: 'template1' // template1, template2, or template3
42
+ companyName: 'Tech Store',
43
+ companyLogo: 'https://example.com/logo.png',
44
+ template: 'template1'
45
+ });
46
+
47
+ // Save to file
48
+ fs.writeFileSync('catalog.pdf', pdfBuffer);
49
+ ```
50
+
51
+ ## Platform Compatibility
52
+
53
+ This library works seamlessly across different JavaScript environments:
54
+
55
+ - ✅ **Node.js** - Backend servers, build scripts, CLI tools
56
+ - ✅ **Browser/React** - Client-side web applications
57
+ - ✅ **Next.js** - Both server components (SSR) and client components
58
+
59
+ ### Browser/React Usage
60
+
61
+ ```typescript
62
+ import { parseExcelFile, generateProductCatalog } from 'pdf-catalog-generator';
63
+
64
+ async function handleFileUpload(event: React.ChangeEvent<HTMLInputElement>) {
65
+ const file = event.target.files?.[0];
66
+ if (!file) return;
67
+
68
+ // Use browser File API
69
+ const arrayBuffer = await file.arrayBuffer();
70
+
71
+ // Parse with ArrayBuffer (cross-platform compatible)
72
+ const products = parseExcelFile(arrayBuffer);
73
+
74
+ // Generate PDF
75
+ const pdfBuffer = await generateProductCatalog({
76
+ products,
77
+ companyName: 'My Store',
78
+ template: 'template1',
79
+ });
80
+
81
+ // Download in browser
82
+ const blob = new Blob([pdfBuffer], { type: 'application/pdf' });
83
+ const url = URL.createObjectURL(blob);
84
+ const link = document.createElement('a');
85
+ link.href = url;
86
+ link.download = 'catalog.pdf';
87
+ link.click();
88
+ URL.revokeObjectURL(url);
89
+ }
90
+ ```
91
+
92
+ ### Next.js Usage
93
+
94
+ **Server Component (App Router):**
95
+ ```typescript
96
+ // app/api/generate-catalog/route.ts
97
+ import { parseExcelFile, generateProductCatalog } from 'pdf-catalog-generator';
98
+
99
+ export async function POST(request: Request) {
100
+ const formData = await request.formData();
101
+ const file = formData.get('file') as File;
102
+
103
+ // Convert File to ArrayBuffer
104
+ const arrayBuffer = await file.arrayBuffer();
105
+
106
+ const products = parseExcelFile(arrayBuffer);
107
+ const pdfBuffer = await generateProductCatalog({
108
+ products,
109
+ companyName: 'My Store',
110
+ });
111
+
112
+ return new Response(pdfBuffer, {
113
+ headers: {
114
+ 'Content-Type': 'application/pdf',
115
+ 'Content-Disposition': 'attachment; filename="catalog.pdf"',
116
+ },
117
+ });
118
+ }
119
+ ```
120
+
121
+ **Client Component:**
122
+ ```typescript
123
+ 'use client';
124
+
125
+ import { useState } from 'react';
126
+ import { parseExcelFile, generateProductCatalog } from 'pdf-catalog-generator';
127
+
128
+ export default function CatalogGenerator() {
129
+ const handleGenerate = async (file: File) => {
130
+ const arrayBuffer = await file.arrayBuffer();
131
+ const products = parseExcelFile(arrayBuffer);
132
+ const pdfBuffer = await generateProductCatalog({
133
+ products,
134
+ companyName: 'My Store',
135
+ });
136
+
137
+ // Download
138
+ const blob = new Blob([pdfBuffer], { type: 'application/pdf' });
139
+ const url = URL.createObjectURL(blob);
140
+ const link = document.createElement('a');
141
+ link.href = url;
142
+ link.download = 'catalog.pdf';
143
+ link.click();
144
+ };
145
+
146
+ return (
147
+ <input
148
+ type="file"
149
+ accept=".xlsx,.csv"
150
+ onChange={(e) => e.target.files?.[0] && handleGenerate(e.target.files[0])}
151
+ />
152
+ );
153
+ }
154
+ ```
155
+
156
+ ### Input Types
157
+
158
+ The parser functions accept multiple input types for cross-platform compatibility:
159
+
160
+ - **Node.js Buffer** - `fs.readFileSync()` returns Buffer
161
+ - **ArrayBuffer** - Browser `File.arrayBuffer()` returns ArrayBuffer
162
+ - **Uint8Array** - Universal typed array format
163
+
164
+ All input types are automatically detected and handled correctly.
165
+
166
+ ## API Reference
167
+
168
+ ### `generateProductCatalog(config)`
169
+
170
+ Generates a PDF catalog from the provided configuration.
171
+
172
+ **Parameters:**
173
+ - `config` (CatalogConfig):
174
+ - `products` (ProductData[]): Array of product data
175
+ - `companyName` (string): Your company name
176
+ - `companyLogo` (string | null, optional): Logo URL or base64 string
177
+ - `template` (TemplateType, optional): Template to use (default: 'template1')
178
+
179
+ **Returns:** `Promise<Uint8Array>` - PDF file as Uint8Array (works in both Node.js and browser)
180
+
181
+ ### `parseExcelFile(buffer)`
182
+
183
+ Parse Excel file buffer into product data.
184
+
185
+ **Parameters:**
186
+ - `buffer` (Buffer | ArrayBuffer | Uint8Array): Excel file data
187
+ - Node.js: Use `Buffer` from `fs.readFileSync()`
188
+ - Browser: Use `ArrayBuffer` from `file.arrayBuffer()`
189
+ - Universal: `Uint8Array` works everywhere
190
+
191
+ **Returns:** `ProductData[]` - Array of products
192
+
193
+ **Example (Node.js):**
194
+ ```typescript
195
+ import { parseExcelFile, generateProductCatalog } from 'pdf-catalog-generator';
196
+ import fs from 'fs';
197
+
198
+ const excelBuffer = fs.readFileSync('products.xlsx');
199
+ const products = parseExcelFile(excelBuffer);
200
+ const pdfBuffer = await generateProductCatalog({
201
+ products,
202
+ companyName: 'My Store'
31
203
  });
204
+ ```
32
205
 
33
- // From Excel file
34
- import { parseExcelFile } from 'pdf-catalog-generator';
206
+ **Example (Browser/React):**
207
+ ```typescript
208
+ import { parseExcelFile, generateProductCatalog } from 'pdf-catalog-generator';
35
209
 
36
- const products = await parseExcelFile(fileBuffer);
210
+ const file = event.target.files[0];
211
+ const arrayBuffer = await file.arrayBuffer();
212
+ const products = parseExcelFile(arrayBuffer);
37
213
  const pdfBuffer = await generateProductCatalog({
38
214
  products,
39
- companyLogo: logoBase64,
40
- companyName: 'Your Company',
41
- template: 'template2'
215
+ companyName: 'My Store'
42
216
  });
217
+ ```
218
+
219
+ ### `parseCSVFile(csvString)`
220
+
221
+ Parse CSV string into product data.
222
+
223
+ **Parameters:**
224
+ - `csvString` (string): CSV content as string
225
+
226
+ **Returns:** `ProductData[]` - Array of products
227
+
228
+ **Example:**
229
+ ```typescript
230
+ import { parseCSVFile, generateProductCatalog } from 'pdf-catalog-generator';
231
+ import fs from 'fs';
232
+
233
+ const csvString = fs.readFileSync('products.csv', 'utf-8');
234
+ const products = parseCSVFile(csvString);
235
+ const pdfBuffer = await generateProductCatalog({
236
+ products,
237
+ companyName: 'My Store'
238
+ });
239
+ ```
240
+
241
+ ### `parseCSVBuffer(buffer)`
242
+
243
+ Parse CSV buffer into product data.
244
+
245
+ **Parameters:**
246
+ - `buffer` (Buffer | ArrayBuffer | Uint8Array): CSV file data
247
+ - Node.js: Use `Buffer` from `fs.readFileSync()`
248
+ - Browser: Use `ArrayBuffer` from `file.arrayBuffer()`
249
+ - Universal: `Uint8Array` works everywhere
250
+
251
+ **Returns:** `ProductData[]` - Array of products
252
+
253
+ ### `parseJSON(data)`
43
254
 
44
- // From CSV file
45
- import { parseCSVFile } from 'pdf-catalog-generator';
255
+ Parse JSON product data. No fields are mandatory - data is passed through as-is.
46
256
 
47
- const products = await parseCSVFile(csvString);
257
+ **Parameters:**
258
+ - `data` (any[]): Array of product objects
259
+
260
+ **Returns:** `ProductData[]` - Products passed through without modification
261
+
262
+ **Note:** parseJSON no longer validates or normalizes data. It simply passes through your data as-is, just like the Excel/CSV parsers.
263
+
264
+ **Example:**
265
+ ```typescript
266
+ import { parseJSON, generateProductCatalog } from 'pdf-catalog-generator';
267
+
268
+ const rawData = [
269
+ { Title: 'Product 1', Link: 'https://example.com/1' },
270
+ { sku: 'ABC-123', name: 'Custom Product', color: 'Blue' },
271
+ { designNumber: 'DN-001', fabric: 'Cotton', gsm: 180 }
272
+ ];
273
+
274
+ const products = parseJSON(rawData); // All pass through without modification
48
275
  const pdfBuffer = await generateProductCatalog({
49
276
  products,
50
- companyLogo: logoUrl,
51
- companyName: 'Your Company',
52
- template: 'template3'
277
+ companyName: 'My Store'
53
278
  });
54
279
  ```
55
280
 
56
- ## Product Data Format
281
+ ## Data Format
282
+
283
+ ### ProductData
284
+
285
+ This library is **completely schema-free** - no fields are mandatory! You can use any data structure you want.
286
+
287
+ ```typescript
288
+ interface ProductData {
289
+ [key: string]: string | number | boolean | null | undefined;
290
+ }
291
+ ```
292
+
293
+ **Dynamic Field Rendering:**
294
+ - All templates automatically detect and display whatever fields you provide
295
+ - Common fields (Title, Description, Image, Price, Rating, Link) are displayed prominently if present
296
+ - All other fields are rendered dynamically with auto-formatted labels
297
+ - Missing fields are gracefully handled - nothing breaks!
57
298
 
58
- Each product should have:
59
- - `Title` (string): Product name
60
- - `Description` (string): Product description
61
- - `Image` (string): Image URL or base64
62
- - `Price` (number): Product price
63
- - `Rating` (number): Star rating
64
- - `Link` (string): Buy/product link
299
+ **Common Field Names (Optional):**
300
+ Templates intelligently look for these common fields (case-insensitive):
301
+ - **Title/Name/ProductName** - Displayed as main heading
302
+ - **Image/ImageUrl/photo** - Used as product image (fallback image if missing)
303
+ - **Description/Details/Info** - Shown as product description
304
+ - **Price/Cost/Amount** - Displayed prominently (formatted if provided)
305
+ - **Rating/Stars/Score** - Shown with star emoji if present
306
+ - **Link/URL/ProductUrl** - Powers "Buy Now" buttons
307
+
308
+ **Custom Fields:**
309
+ Any other fields are automatically displayed with smart formatting:
310
+ - `designNumber` → "Design Number"
311
+ - `gsm` → "GSM" (uppercase for known acronyms)
312
+ - `fabric_finish` → "Fabric Finish"
313
+
314
+ **Example - Traditional E-commerce:**
315
+ ```typescript
316
+ {
317
+ Title: 'Laptop Pro 15',
318
+ Description: 'High-performance laptop',
319
+ Image: 'https://example.com/laptop.jpg',
320
+ Price: 1299.99,
321
+ Rating: 4.5,
322
+ Link: 'https://store.example.com/laptop'
323
+ }
324
+ ```
325
+
326
+ **Example - Custom Textile Catalog:**
327
+ ```typescript
328
+ {
329
+ designNumber: 'DN-12345',
330
+ fabric: '100% Cotton',
331
+ gsm: 180,
332
+ finish: 'Mercerized',
333
+ color: 'Navy Blue',
334
+ Image: 'https://example.com/fabric.jpg'
335
+ }
336
+ ```
337
+
338
+ **Example - Minimal:**
339
+ ```typescript
340
+ {
341
+ name: 'Widget',
342
+ sku: 'WDG-001'
343
+ }
344
+ ```
345
+
346
+ All of the above work perfectly! Templates adapt to your data structure.
65
347
 
66
348
  ## Templates
67
349
 
68
- - `template1`: Grid layout with 2 columns
69
- - `template2`: Full-width list layout
70
- - `template3`: Compact grid layout
350
+ All templates are **fully dynamic** and adapt to your data structure. They intelligently detect common fields and display all additional fields automatically.
351
+
352
+ ### Template 1: Grid Layout
353
+ 2-column grid layout with product cards. Perfect for showcasing multiple products.
354
+
355
+ ```typescript
356
+ template: 'template1'
357
+ ```
358
+
359
+ **Best for:** Products with mixed field types - automatically displays all fields in a compact grid card.
360
+
361
+ ### Template 2: List Layout
362
+ Full-width horizontal layout with image on left, details on right. Great for detailed product information.
363
+
364
+ ```typescript
365
+ template: 'template2'
366
+ ```
367
+
368
+ **Best for:** Detailed products - shows all fields with room for descriptions and custom attributes.
369
+
370
+ ### Template 3: Full Page Layout
371
+ Full-page product view with image background and overlay details box. One product per page.
372
+
373
+ ```typescript
374
+ template: 'template3'
375
+ ```
376
+
377
+ **Best for:** Premium catalogs with hero images - displays key fields in an elegant overlay box (shows up to 5 custom fields).
378
+
379
+ ### Template 4: One-Per-Page
380
+ Full-page product view with header on each page and all product details listed. One product per page.
381
+
382
+ ```typescript
383
+ template: 'template4'
384
+ ```
385
+
386
+ **Best for:** Maximum detail - displays ALL product fields with formatted labels. Ideal for technical specifications or textile catalogs.
387
+
388
+ ## TypeScript Support
389
+
390
+ This package is written in TypeScript and includes type definitions:
391
+
392
+ ```typescript
393
+ import type { CatalogConfig, ProductData, TemplateType } from 'pdf-catalog-generator';
394
+
395
+ const config: CatalogConfig = {
396
+ products: [],
397
+ companyName: 'My Company',
398
+ template: 'template1'
399
+ };
400
+ ```
401
+
402
+ ## Examples
403
+
404
+ Check the `examples/` directory for complete working examples:
405
+ - Basic usage
406
+ - Excel to PDF
407
+ - CSV to PDF
408
+ - Custom templates
409
+
410
+ ## Development
411
+
412
+ ```bash
413
+ # Install dependencies
414
+ npm install
415
+
416
+ # Run tests
417
+ npm test
418
+
419
+ # Run tests with coverage
420
+ npm run test:coverage
421
+
422
+ # Build package
423
+ npm run build
424
+
425
+ # Run Storybook
426
+ npm run storybook
427
+
428
+ # Lint code
429
+ npm run lint
430
+
431
+ # Format code
432
+ npm run format
433
+ ```
434
+
435
+ ## Contributing
436
+
437
+ Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
438
+
439
+ ## Changelog
440
+
441
+ See [CHANGELOG.md](CHANGELOG.md) for a list of changes.
442
+
443
+ ## License
444
+
445
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
446
+
447
+ ## Support
448
+
449
+ - 📚 [Documentation](https://github.com/yourusername/pdf-catalog-generator)
450
+ - 🐛 [Issue Tracker](https://github.com/yourusername/pdf-catalog-generator/issues)
451
+ - 💬 [Discussions](https://github.com/yourusername/pdf-catalog-generator/discussions)
452
+
453
+ ## Credits
71
454
 
455
+ Built with:
456
+ - [@react-pdf/renderer](https://github.com/diegomura/react-pdf) - PDF generation
457
+ - [xlsx](https://github.com/SheetJS/sheetjs) - Excel/CSV parsing
458
+ - [TypeScript](https://www.typescriptlang.org/) - Type safety
459
+ - [Vitest](https://vitest.dev/) - Testing
460
+ - [Storybook](https://storybook.js.org/) - Documentation