bookjs-eazy

repository·master·Indexed 42 days ago

https://github.com/wuxue107/bookjs-eazy

A specialized tool for converting HTML content into high-quality, paginated PDFs using H5/CSS. Version 1.17.0 features automatic pagination, WYSIWYG preview, and flexible deployment via browser 'Print to PDF', Chrome Headless, or wkhtmltopdf. It provides a system for controllable page breaks using data-op-type attributes (block, text, new-page, pendants, mix-box, and table) and includes plugins for page numbering, tables of contents, and PDF bookmarks.

Tokens
15.8K
Snippets
52
Records
68
Agent score
53%

What's inside bookjs-eazy

  1. Overview of bookjs-eazy

    master

    bookjs-eazy is a tool for WEB printing and converting HTML to PDF. It solves the problem of controllable pagination when generating high-quality PDFs from HTML content.

    Key Features:

    • Automatic Pagination: Focus on building content with H5/HTML; the tool handles pagination and content truncation based on defined rules.
    • WYSIWYG Preview: Supports web printing and previewing with custom page numbers, tables of contents, headers, and footers.
    • Flexible Deployment: Can be used on the frontend (browser 'Print to PDF') or backend (using Chrome Headless or wkhtmltopdf).
    • Docker Support: Provides a Docker image for quick deployment of a PDF generation service.

    Important Limitations:

    • Framework Compatibility: Does not support modern SPA routing (Vue, React, etc.) via import. You must include scripts directly via <script> tags in the HTML.
    • No Dynamic Refresh: Re-rendering requires a full page refresh.
    • Entry Point: Each PDF page requires its own dedicated HTML file entry point.
    • Embedding: To embed within an existing web application, use an <iframe>.
  2. Deprecated: Use mix-box instead of block-box or text-box

    master

    The block-box and text-box types are deprecated. Their functionality has been fully replaced by mix-box.

    • block-box: Previously used to treat children of a .nop-fill-box as indivisible blocks that repeat the container when spanning pages.
    • text-box: Previously used for large text blocks that repeat the container when spanning pages.

    Recommendation: Use mix-box with text or block children for all new implementations.

  3. Important limitations and constraints

    master

    When using bookjs-eazy, be aware of the following technical constraints:

    • Framework Compatibility: Modern single-page application (SPA) frameworks like Vue or React are not supported in their standard routing/import modes. Script tags must be directly introduced in the HTML rather than being compiled via import statements.
    • Dynamic Content: Dynamic refreshing is not supported. To re-render, the entire page must be refreshed.
    • Page Entry: Each PDF page requires its own separate HTML file entry.
    • Embedding: To embed the tool within an existing web application, use the <iframe> method.
    • Custom Paper/Printing: For pages using custom paper sizes, ensure you use Chrome's "Print $\rightarrow$ Save as PDF" or have the corresponding printer/paper profiles installed. Using Chrome Headless or wkhtmltopdf avoids these browser-specific printing issues.
  4. How the rendering mechanism works

    master

    To render a page for PDF generation, follow these steps:

    1. Structure: Place your PDF content elements inside a container with the ID #content-box under the <body> tag.
    2. Trigger Rendering: The program monitors the global variable window.bookConfig.start. Rendering only begins when this value is set to true.
      • Crucial for Dynamic Content: If your page content is loaded dynamically, set window.bookConfig.start to false by default. Once your content is fully loaded and ready, switch it to true to trigger the PDF styling and pagination logic.
    3. Overflow Detection: The tool uses a container node with the class .nop-page-content to detect page overflows by monitoring height changes.

    Layout Best Practices to avoid overflow detection issues:

    • Avoid certain CSS properties: Elements using display: float, position: absolute, or overflow may not trigger height changes in the container, causing undetected overflows.
    • Use Padding instead of Margin: Elements with margin styles cannot expand the size of .nop-page-content, which can cause position offsets and unexpected overflows. Use padding to control relative spacing instead.
  5. Design PDF content using data-op-type

    master

    To design a PDF document with bookjs-eazy, you must define a container node with id="content-box". All content intended for the PDF must be placed inside this container. Each first-level child of #content-box must include a data-op-type attribute to instruct the engine on how to handle paging and layout.

    Core Rules:

    • Use data-op-type to define the behavior of nodes (e.g., block, text, new-page, pendants, mix-box, table).
    • Most types can be nested within container nodes like mix-box, table, block-box, or text-box.
    • Important: Do not set height or max-height on box or container nodes, as this interferes with the engine's overflow detection.
    <body>
    <div id="content-box">
      <p data-op-type="text">Hello World! </p>
    </div>
    </body>
  6. Design PDF content pagination with data-op-type

    master

    To design a PDF document, you must define a container element with id="content-box". All direct children of this container must use the data-op-type attribute to specify how they should be inserted and handled during pagination.

    Core Rules:

    • The root container must be <div id="content-box">.
    • Use data-op-type on direct children to control flow.
    • block and text types can be nested inside container types (like mix-box or table), but other types generally cannot be nested.
    • Important: Do not set fixed heights (e.g., height or max-height) on container nodes, as this interferes with overflow detection and pagination.
    <body>
        <div id="content-box">
            <p data-op-type="text">Hello World!</p>
        </div>
    </body>
  7. Quick start with Docker

    master

    To quickly experience the PDF generation service using Docker:

    1. Download or clone the repository.
    2. Navigate to the project directory in your terminal.
    3. Run the startup script:
      • On Linux/macOS: ./docker-start.sh
      • On Windows: docker-start.bat
    4. Access the demo at http://127.0.0.1:3000/eazy-1.html to test printing and PDF creation.

    You can place your own PDF page designs in the dist directory.

    ./docker-start.sh
  8. Configure page parameters with bookConfig

    master

    To use bookjs-eazy, you must define a global configuration object named bookConfig. This object controls paper size, orientation, margins, and various plugins like page numbering, catalogs, and toolbars.

    Critical: Handling Dynamic Content

    If your page content is generated dynamically (e.g., via asynchronous requests or charts), you must set bookConfig.start to false initially. Only set it to true once your #content-box node is fully rendered and ready. This ensures the library doesn't attempt to paginate an empty or incomplete container.

    Core Configuration Options

    • start (boolean): Controls when rendering begins. Set to true to start.
    • pageSize (string): Paper size (e.g., 'ISO_A4').
    • orientation (string): 'portrait' or 'landscape'.
    • pageSizeOption (object): Custom dimensions using width and height (e.g., { width: '15cm', height: '20cm' }).
    • padding (string): Page margins (e.g., '31.8mm 25.4mm 31.8mm 25.4mm').
    • pageFixedHeightOffset (number): Adjusts height to prevent blank pages caused by browser rendering differences (unit: mm, typically negative).
    • printDelay (number): Milliseconds to wait before PDF generation (affects server-side printing only).
    <script>
      bookConfig = {
        // Set to false if content is loaded asynchronously
        start: true,
        pageSize: 'ISO_A4',
        orientation: 'landscape',
        padding: '31.8mm 25.4mm 31.8mm 25.4mm',
        pageFixedHeightOffset: -1.0,
        forcePrintBackground: true,
        printDelay: 1000
      };
    </script>
  9. Configure fonts for consistent PDF generation

    master

    To ensure the generated PDF matches the browser preview, install required fonts on the PDF generation server.

    If using Docker, place font files in ./dist/fonts/ for automatic loading.

    To prevent rendering inconsistencies and speed up generation, use @font-face to define a local alias and prioritize the original font name in your CSS. This prevents delays caused by downloading large network fonts.

    <style>
        @font-face {
            font-family: YH;
            src: url(./fonts/msyh.ttf);
            font-weight: 400;
            font-style: normal
        }
    
        body {
            font-family: "Microsoft YaHei", YH, sans-serif;
            font-weight: normal;
        }
    </style>
  10. Install and run the screenshot-api-server manually

    master

    If you prefer not to use Docker, you can install the screenshot-api-server manually. This requires Node.js and Yarn.

    1. Clone the repository: git clone https://gitee.com/wuxue107/screenshot-api-server.git
    2. Navigate to the directory: cd screenshot-api-server
    3. Install dependencies: yarn
    4. Start the service: yarn start

    Environment Variables:

    • MAX_BROWSER: Maximum Puppeteer instances (default: [Available Memory]/200M).
    • PDF_KEEP_DAY: Automatically delete files older than n days (default: 0, no deletion).
    • PORT: Listening port (default: 3000).

    To use this service, configure bookConfig.toolBar.serverPrint.serverUrl to //your-screenshot-api-server[:PORT]/.

    git clone https://gitee.com/wuxue107/screenshot-api-server.git
    cd screenshot-api-server
    yarn
    yarn start
  11. Configure page parameters via bookConfig

    master

    To use bookjs-eazy, you must define a global configuration object named bookConfig in a <script> tag. This object controls page dimensions, orientation, margins, and plugin behaviors.

    Critical Configuration: start

    If your page contains dynamic content (e.g., asynchronous requests, charts, or complex HTML rendering), set bookConfig.start to false initially. Once the content is fully rendered and ready, set it to true to trigger the bookjs-eazy rendering process.

    Page Dimensions and Orientation

    You can define the page size using either standard ISO/JIS/NA types or custom dimensions:

    • pageSize: A string representing standard sizes (e.g., 'ISO_A4', 'NA_LETTER', 'JIS_B5'). Default is 'ISO_A4'.
    • orientation: 'portrait' or 'landscape'.
    • pageSizeOption: Use this for custom dimensions instead of pageSize. It requires width and height (e.g., '15cm').

    Margins and Layout

    • padding: A string defining margins (e.g., '31.8mm 25.4mm 31.8mm 25.4mm').
    • pageFixedHeightOffset: A value in mm (often negative) used to fix issues where browsers add extra blank pages during printing.
    • forcePrintBackground: Boolean to force printing of background elements. Default is true.
    • printDelay: Time in milliseconds to wait before generating the PDF. Useful for pages with unpredictable asynchronous elements.
    <script>
    bookConfig = {
        start: true, // Set to true only when all dynamic content is ready
        pageSize: 'ISO_A4',
        orientation: 'landscape',
        padding: '31.8mm 25.4mm 31.8mm 25.4mm',
        printDelay: 1000
    };
    </script>
  12. Deploy the PDF generation service via Docker

    master

    You can quickly deploy a self-hosted printing service using the provided Docker script. This creates a web server with dist as the root directory.

    1. Run the script: ./docker-start.sh [WEB_PORT] (defaults to 3000).
    2. Access the sample at http://127.0.0.1:3000/eazy-1.html.
    3. Place your book.html in the dist directory to preview and print via the server.
    4. Generated PDFs will be stored in the dist/pdf/ directory.
    # Run the print service (default port 3000)
    ./docker-start.sh