PDF Microservice
URL: https://pdf.microservices.hexlabs.co.uk
This allows us to rapidly build pdfs.
Overview
This uses puppeteer that visits a page and saves the pdf template. Any data passed into the request body will be added to localStorage for use in the pdf template.
PDF design features are added to the page using the ~/layouts folder. All elements to show up on every file should be using position fixed.
Multiple pages can be grouped and will be merged before being stored in firebase storage.
How it works
- Request is sent to server specifying the pages to be used.
- A puppeteer client is started.
- Any
datarecieved by the server is loaded into the puppeteer clients localStorage. - Puppeteer loads the appropriate page.
- The localStorage is put into a reactive variable store to be used by the page.
- Page breaks are dynamically added to the page.
- The PDF is saved by puppeteer.
- All pages are concatanated in order and uploaded to firebase storage.
- A return value is sent back.
Adding new templates
- Create a layout. The layout should have
#footerand#headeritems with fixed positioning. - Create
~/pages/<new-layout-name>/<pdf-name> - Write in
<pdf-name>.vuethe content of the document. - Create a
~/pages/<layout-name>/dev-data/<pdf-name>.jsonfile with the data that will be added to the page. This will automatically populate the page inDEVmode. (specify in~/flags.ts)
Note
- The header and footer should be visible and be fixed.
- Line breaks will be auto added
- Its important to make a
~/pages/<folder-name>folder for each layout so they can be picked from the api.
This needs to be added to every page to expose data and dynamically add page breaks.
const { data } = await pdfOnMount({
path: useRoute().path,
})Development
- In your dev tools make the screen size
800pxx1125pxto mimic the pdf size.
Note: You can make a custom screen size in Chrome Dev Tools for ease of use.
Endpoints
POST: /api/pdf
For now this is the only endpoint.
All pages passed here will be concatanated into a single document.
interface RequestBody {
pages: {
page: string
layout: string
data: any
}[]
fileName: string // what the file will be named
}The return object will be:
interface ProjectFile {
id: string
name: string
size: number
mime: "application/pdf"
timestamp: number
lastModified: number
previewUrl: string
downloadUrl: string
}POST: /api/dev/pdf
Does the same as the above but uses the <dev-data>.json file instead.
interface RequestBody {
pages: {
page: string
layout: string
}[]
}