Node bindings for pdftk and xpdf. It is assumed these libraries are installed and that there is a file system.
If using docker, install the above libraries by adding this to the Dockerfile:
## install pdftk
RUN apt update -y
RUN apt-get install software-properties-common -y
RUN add-apt-repository ppa:malteworld/ppa
RUN apt-get install pdftk -y
## install xpdf
RUN apt-get install xpdf -y
## install node
RUN apt-get install curl -y
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash
RUN apt-get install nodejs -y
init() takes the path to the temporary folder as argument and returns all the functions as below but curried and with tempFolder already set.
import { init } from './index'
const tempFolder = `${__dirname}/temp`
const fixPolicy = await (inputPath: string, outputPath: string) => {
const { removePages, addRect, addImage, replaceText, bufferToFile } = init(tempFolder)
const removePage10 = removePages([10])
const hidePaxLogo = addRect({
width: 100,
height: 40,
x: 470,
y: 25,
})
const addCreadiLogo = addImage({
imagePath: image,
width: 100,
height: 40,
x: 470,
y: 25,
})
const replacePaxWithCreadi = replaceText({
textToReplace: 'Pax, Schweizerische Lebensversicherungs-Gesellschaft AG',
newText: 'Creadi AG',
})
const buffer = await pipeP(
removePage10,
hidePaxLogo,
addCreadiLogo,
replacePaxWithCreadi,
)(inputPath)
await bufferToFile(outputPath, buffer)
}
fixPolicy(
`${__dirname}/pax_policy.pdf`,
`${__dirname}/creadi_policy.pdf`
)For most of the following functions the input pdf can be the path to a pdf file or a buffer.
type PathOrBuffer = string | Bufferexport interface AddImageConfig {
height: number
imagePath: string
page?: number
width: number
x: number
y: number
}
addImage: (tempFolder: string, config: AddImageConfig, pdf: PathOrBuffer) => Promise<Buffer>If config.page is defined, the image will only be added to that page. Otherwise it will be added to all pages.
Add a rectangle to hide previous content.
export interface AddRectConfig {
color?: string
height: number
page?: number
width: number
x: number
y: number
}
addRect: (tempFolder: string, config: AddRectConfig, pdf: PathOrBuffer) => Promise<Buffer>If config.color is not defined, defaults to white.
If config.page is defined, the image will only be added to that page. Otherwise it will be added to all pages.
export interface AddTextStyle {
font?: Font
fontSize?: number
}
export interface AddTextConfig {
style?: AddTextStyle
texts: {
coordinates: number[]
page: number
fontSize?: number
text: string
}[]
}
addText: (tempFolder: string, config: AddTextConfig, pdf: PathOrBuffer) => Promise<Buffer>Save a buffer to a file
bufferToFile: (outputPath: string, buffer: Buffer) => Promise<void>(pdf: PathOrBuffer, tempFolder?: string | undefined) => Promise<number>tempFolder only needs to be passed if pdf is a buffer. It will throw an error if pdf is a buffer and tempFolder is undefined.
interface Text {
page: number
text: string
size: number[]
}
extractText: (pdf: PathOrBuffer, tempFolder?: string | undefined) => Promise<Text[]>tempFolder only needs to be passed if pdf is a buffer. It will throw an error if pdf is a buffer and tempFolder is undefined.
keepPages: (tempFolder: string, pagesToKeep: number[], pdf: PathOrBuffer) => Promise<Buffer>merge: (filePaths: string[], tempFolder: string) => Promise<Buffer>All functions clean up temporary files if they run successfully. This should be used in catch to clean up if something goes wrong
purgeTemp: (tempFolder: string) => Promise<void>removePages: (tempFolder: string, pagesToRemove: number[], pdf: PathOrBuffer) => Promise<Buffer>render: (dd: any, font?: "Courier" | "Helvetica" | undefined) => Promise<Buffer>Where dd is a pdfmake document definition. There are no usable types for it but an excellent typed library to generate them with JSX: pdfmakejsx :-D
export interface ReplaceTextConfig {
newText: string
page?: number
textToReplace: string
}
replaceText: (tempFolder: string, config: ReplaceTextConfig, pdf: PathOrBuffer) => Promise<Buffer>