Skip to content

Latest commit

 

History

History
 
 

README.md

Accessible PDF Generation

This package provides an API and templates for generating accessible PDFs on the client side.

Development

General

To update dependent packages:

yarn workspace @department-of-veterans-affairs/platform-pdf install

Creating new templates

To add a new PDF template, create a new file under the templates directory and add it to templates/index.js so that it can be used. The filename is used as the key when generating PDF content. First consider if an existing template can meet your project's needs. PDFKit is powerful but tricky to work with, so it's worth following existing templates and making small iterations. Various utility methods are available in the utils.js file. Once a new template has been completed, sample output files must be reviewed by the Platform Accessibility team to ensure that they are fully compliant.

Validation / Error handling

Your template should throw an exception for any unrecoverable states. See the validation method in the Medical Records template and MissingFieldsException for an example.

Testing changes

If you are testing changes to a template, the fastest way to test changes is to use the following command to only build changes to the PDF package and the app you are testing. For instance, if you are testing changes with the Medical Records app, you would use the following command:

yarn --cwd $( git rev-parse --show-toplevel ) watch --env entry=pdf,medical-records

NB: you will need to kill and re-start the watch command after each change to the PDF application to see changes.

Usage

This package provides a single API method for generating PDFs.

generatePdf('template_name', 'generated_file_name', jsonData);

Example usage in a VA.gov React application:

import { generatePdf } from '@department-of-veterans-affairs/platform-pdf/exports';

const generateVitals = async () => {
  // This data would usually be dynamically generated.
  const pdfData = {
      "headerLeft": "Lastname, Firstname",
      "headerRight": "Date of birth: January 1, 1970",
      "footerLeft": "Report generated by My HealtheVet and VA on May 15, 2023",
      "footerRight": "Page %PAGE_NUMBER% of %TOTAL_PAGES%",
      "title": "Blood pressure on April 1, 2022 at 12:34 p.m.",
      "subject": "VA Medical Record",
      "preface": "Your vitals list may not be complete. If you have any questions about your information, visit the FAQs or contact your VA Health care team.",
      "results": {
        "items": [
          {
            "items": [
              {
                "title": "Result",
                "value": "120/80",
                "inline": true
              },
              {
                "title": "Location",
                "value": "Pittsburgh VA Medical Center",
                "inline": true
              },
              {
                "title": "Provider notes",
                "value": "None noted",
                "inline": true
              }
            ]
          }
        ]
      }
  };

  try {
    await generatePdf('medicalRecords', 'vitals_report', pdfData);
  } catch (error) {
    // Error logging/presentation goes here...
  }
};

When called, the PDF will be generated and the end user's browser will prompt download with the filename vitals_report.pdf. Be sure to catch, log and gracefully handle errors to provide the best end user experience possible.

Limitations

Character set support

As of June 2023, PDFKit does not support font fallback, meaning that any character that doesn't have a glyph in the selected font will not render. In practice, this means that non-roman characters and multibyte characters (such as emoji) will not render without using a template and font built to support your use case. To see if a specific character is supported, you can use a tool such as Oh My Glyph to load a font and see supported glyphs.

PDF Metadata

The following fields must be provided by the caller in the JSON data:

  • Title

The following fields should be provided, but are not required:

  • Author (defaults to "Department of Veterans Affairs")
  • Language (defaults to "en-US")
  • Subject (defaults to blank)