1.2.1 • Published 2 months ago

@spexzee/react-pdfhook v1.2.1

Weekly downloads
-
License
MIT
Repository
github
Last release
2 months ago

React PDF Generator Hook - @spexzee/react-pdfhook

npm license downloads types

A production-ready React hook for generating high-fidelity PDFs with advanced layout control and content targeting.

Main Issue solved : if data doesn't fit in a remaining screen it will start from next page

Features

  • Precision PDF Generation

    • Convert React components to pixel-perfect PDFs
    • Support for all HTML/CSS that html2canvas can render
    • Automatic and manual page break controls
  • Advanced Content Targeting

    • Flexible selector system for specific elements
    • PDF-only content visibility (show in PDF but hide in browser)
    • Image handling with CORS support
  • Layout Control

    • Fixed-width mode for consistent cross-device rendering
    • Responsive design preservation
    • Customizable margins and page formats

Installation

npm install @spexzee/react-pdfhook 
# or
yarn add @spexzee/react-pdfhook 

Basic Usage

import { usePdfGenerator } from '@spexzee/react-pdfhook';
import Image from './images/header.jpg'

function DocumentGenerator() {
  const { generatePdf, pdfRef } = usePdfGenerator({
    fileName: 'document.pdf'
  });

  const handleDownload = async () => {
  // manually add which elements we wants in pdf 
  await generatePdf([
    {
      selector: Image.src,
      mapping: false,
      type: 'image',
      imageOptions: {
        width: 180, // mm
        maintainAspectRatio: true
      }
    },
    { 
      selector: '.header-content', 
      mapping: false,
      type: 'element' 
    },
    { 
      selector: '.multi-data', 
      // advantage of using mapping , it will single single data into pdf , so we can easilt manage page-breaks , 

      // if data doesn't fit in a remaining screen it will start from next page
      mapping: true, 
      type: 'element' 
    }
  ]);

};

  return (
    <div>
      <button onClick={handleDownload}>Generate PDF</button>
      <div ref={pdfRef}>
        <div className="header-content">
            <h1>My Document</h1>
            <p>This content will appear in the PDF</p> 
        </div>
        {
            data.map((x)=>(
                <div className="multi-data"> 
                    <AnyComponentName data={x}>
                </div>
            ))
        }
      </div>
    </div>
  );
}

Normal Function example

Component Implementation

import React, { useRef } from 'react';
import { usePdfGenerator } from '@spexzee/react-pdfhook';

const SimplePdfExport = () => {
  const { exportToPdf, pdfRef, pdfLoading } = usePdfGenerator({
    fileName: 'my-document',
  });

  return (
    <div>
      <button onClick={exportToPdf} disabled={pdfLoading}>
        {pdfLoading ? 'Generating...' : 'Export PDF'}
      </button>

      {/* This div's contents will be converted to PDF */}
      <div ref={pdfRef} style={{ padding: '20px' }}>
        <h1>Document Title</h1>
        
        <div className="section">
          <h2>Section 1</h2>
          <p>This content will be processed (parent element)</p>
          
          <div className="subsection">
            <p>Nested content 1 (child element)</p>
            <p>Nested content 2 (child element)</p>
          </div>
        </div>
        
        <div className="footer">
          <p>This footer has no children and will be processed directly</p>
        </div>
      </div>
    </div>
  );
};

export default SimplePdfExport;

2. PDF-Only Content

<div ref={pdfRef}>
  {/* Visible in both browser and PDF */}
  <h1>Public Report</h1>
  
  {/* Hidden in browser, visible only in PDF */}
  <div className="pdf-only">
    <h2>Confidential Details</h2>
    <p>Only visible in the generated PDF</p>
  </div>
</div>

2. Screen-Only Content

<div ref={pdfRef}>
  {/* Visible in both browser and PDF */}
  <h1>Public Report</h1>
  
  {/* Hidden in pdf, visible only in browser */}
  <div className="screen-only">
    <h2>Confidential Details</h2>
    <p>Only visible in the generated PDF</p>
  </div>
</div>

Required CSS for PDF Only:

.pdf-only {
  display: none;
}

@media print {
  .pdf-only {
    display: block;
  }
}

3. Layout Control

const { generatePdf } = usePdfGenerator({
  fixedWidth: 1200, // pixels (optimal for A4 width)
  scale: 1.5, // Quality/performance balance
  margin: { top: 20, right: 15, bottom: 20, left: 15 }, // mm
  pageBreak: true
});

Complete API Reference

Hook Configuration

OptionTypeDefaultDescription
fileNamestring'document.pdf'Output filename
formatstring/array'a4'Page size (a3,a4,letter or w,h in mm)
orientationstring'portrait''portrait' or 'landscape'
marginnumber/object0Margins in mm
fixedWidthnumberundefinedConstrained width in pixels
scalenumber2Render quality multiplier
pageBreakbooleantrueAuto page break config
imageQualitynumber1Image quality (0-1)
debugbooleanfalseEnable debug logging
compressPdfbooleantrueCompress the pdf size

Content Configuration

interface PdfContentItem {
  selector: string;       // CSS selector or image path
  mapping: boolean;      // true = all matches, false = first match
  type: 'element'|'image';
  imageOptions?: {        // Only for type: 'image'
    width?: number;      // mm
    height?: number;     // mm
    x?: number;          // mm
    y?: number;          // mm
    format?: 'JPEG'|'PNG';
    maintainAspectRatio?: boolean;
  };
}

Best Practices

  1. For images:

    • Place assets in public folder
    • Use absolute paths (/images/photo.jpg)
    • Set explicit dimensions in imageOptions
  2. For performance:

    {
      scale: 1, // Lower quality but faster
      imageQuality: 0.8,
      fixedWidth: 800 // Smaller fixed width
    }

Troubleshooting

IssueSolution
Images missingVerify paths and CORS headers
Content clippedIncrease margins or reduce fixedWidth
PDF-only content not showingCheck CSS and media queries
Performance problemsReduce scale and imageQuality

License

MIT © Spexzee


Like this package? ⭐️ Star the repo
Need help? 📧 Contact me
Found a bug? 🐛 Open an issue

1.2.1

2 months ago

1.2.0

2 months ago

1.1.0

2 months ago

1.0.4

4 months ago

1.0.3

4 months ago

1.0.2

4 months ago

1.0.1

4 months ago

1.0.0

4 months ago