Skip to content
This repository has been archived by the owner on Jan 17, 2023. It is now read-only.

Commit

Permalink
add html header option
Browse files Browse the repository at this point in the history
  • Loading branch information
moshensky committed Jan 16, 2018
1 parent 55e3641 commit d20d56f
Show file tree
Hide file tree
Showing 11 changed files with 33 additions and 37 deletions.
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,16 @@ export const getPDFWithCustomSize = (document: string): Buffer =>

## Roadmap

- add headers (asap in a day or two)
- document API
- provide more examples using `javascript`
- load document from URL, wait for all resources do be loaded (css, js, images, fonts, etc.), wait for javascript execution and than generate PDF
- setup CI
- cover with tests
- option to configure reusing chrome instances
[x] add html headers
[ ] add text headers
[ ] document API
[ ] provide more examples using `javascript`
[ ] load document from URL, wait for all resources do be loaded (css, js, images, fonts, etc.), wait for javascript execution and than generate PDF
[x] setup CI
[x] cover with tests
[ ] add performance tests
[ ] option to configure reusing chrome instances
[ ] use puppeteer header/footer template only when there is no need for different headers/footers per different pages

## How to run tests

Expand Down Expand Up @@ -164,5 +167,3 @@ If pdf comparing tests would fail, an image diff would be generated inside `outp
[coveralls-url]: https://coveralls.io/github/moshensky/html-to-pdf-converter?branch=master
[snyk-badge-url]: https://snyk.io/test/github/moshensky/html-to-pdf-converter/badge.svg?targetFile=package.json
[snyk-url]: https://snyk.io/test/github/moshensky/html-to-pdf-converter?targetFile=package.json


Binary file modified expected/htmlFooter.pdf
Binary file not shown.
Binary file modified expected/htmlFooter00.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified expected/htmlFooter01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added expected/singlePageWithHtmlHeader.pdf
Binary file not shown.
Binary file added expected/singlePageWithHtmlHeader.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified expected/textFooter.pdf
Binary file not shown.
7 changes: 4 additions & 3 deletions src/compound-pdf.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const puppeteerOptions: MkPdfOptions = {
}

const TEST_TIMEOUT = 10000 // 10 seconds
const OUTPUT_NEW_EXPECTED_FILES = false

describe('mkCompoundPdf()', () => {
it(
Expand Down Expand Up @@ -62,7 +63,7 @@ describe('mkCompoundPdf()', () => {
puppeteerOptions,
)

await compareToExpected('textFooter', pdfBuffer, false)
await compareToExpected('textFooter', pdfBuffer, OUTPUT_NEW_EXPECTED_FILES)
},
TEST_TIMEOUT,
)
Expand Down Expand Up @@ -95,7 +96,7 @@ describe('mkCompoundPdf()', () => {
puppeteerOptions,
)

await compareToExpectedMultiple('htmlFooter', pdfBuffer, false)
await compareToExpectedMultiple('htmlFooter', pdfBuffer, OUTPUT_NEW_EXPECTED_FILES)
},
TEST_TIMEOUT,
)
Expand All @@ -118,7 +119,7 @@ describe('mkCompoundPdf()', () => {
puppeteerOptions,
)

await compareToExpected('singlePageWithHtmlHeader', pdfBuffer, true)
await compareToExpected('singlePageWithHtmlHeader', pdfBuffer, OUTPUT_NEW_EXPECTED_FILES)
},
TEST_TIMEOUT,
)
Expand Down
26 changes: 8 additions & 18 deletions src/compound-pdf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const calcSlotSize = async (

return {
width: pageSize.width.subtract(margin.left).subtract(margin.right),
height: height.add(Millimeters.of(4)), // add top padding to footer of 4 mm
height: height.add(Millimeters.of(4)), // add top padding to footer of 4 mm for text slot
}
}
default:
Expand All @@ -47,21 +47,11 @@ const mkPdfWithSpaceForSlots = async (
): Promise<PdfWithSpaceForSlots> => {
const headerSize = header ? await calcSlotSize(header, margin, pageSize, page) : PageSize.ofZero()
const footerSize = footer ? await calcSlotSize(footer, margin, pageSize, page) : PageSize.ofZero()
const pdfBuffer = await mkSizedPdf(
pdfContent,
page,
// TODO: evaluate whether this is still needed
{
height: pageSize.height,
// adjust page width according to rounded footer width
width: footerSize.width.add(margin.left).add(margin.right),
},
{
...margin,
top: margin.top.add(headerSize.height),
bottom: margin.bottom.add(footerSize.height),
},
)
const pdfBuffer = await mkSizedPdf(pdfContent, page, pageSize, {
...margin,
top: margin.top.add(headerSize.height),
bottom: margin.bottom.add(footerSize.height),
})

return {
mainPdf: pdfBuffer,
Expand Down Expand Up @@ -93,9 +83,9 @@ const addSlotToPdf = async (args: AddHeaderFooterToPdfArgs): Promise<Buffer> =>
startFromPage + pagesCount,
totalPagesCount,
)
const pdfContent = await mkSizedPdf(htmlContent, page, size)
const slotPdf = await mkSizedPdf(htmlContent, page, size)

return mergePdfs(pdf, pdfContent, margin, slotType)
return mergePdfs(pdf, slotPdf, margin, slotType, size)
}
case 'TextSlot': {
if (slotType === 'header') {
Expand Down
13 changes: 9 additions & 4 deletions src/hummus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from 'hummus'
import { ReadStreamForBuffer } from './read-stream-for-buffer'
import { PDFStreamForBuffer } from './pdf-stream-for-buffer'
import { PrintMargin, TextSlot, PdfPoints, SlotType } from './types'
import { PrintMargin, TextSlot, PdfPoints, SlotType, PageSize } from './types'

interface PageInfo {
width: PdfPoints
Expand Down Expand Up @@ -118,7 +118,13 @@ export const addFooter = (args: AddFooterArgs) => {
return outputBuffer.getBuffer()
}

export const mergePdfs = (target: Buffer, source: Buffer, margin: PrintMargin, type: SlotType) => {
export const mergePdfs = (
target: Buffer,
source: Buffer,
margin: PrintMargin,
type: SlotType,
slotSize: PageSize,
) => {
const targetReader = createReader(new ReadStreamForBuffer(target))
const targetFirstPage = targetReader.parsePage(0)
const targetMediaBox = targetFirstPage.getMediaBox()
Expand All @@ -139,8 +145,7 @@ export const mergePdfs = (target: Buffer, source: Buffer, margin: PrintMargin, t
const yPos =
type === 'footer'
? PdfPoints.of(targetMediaBox[3]).subtract(margin.bottom.toPdfPoints())
: // TODO: find out that part
PdfPoints.of(targetMediaBox[0]).subtract(margin.top.toPdfPoints())
: slotSize.height.toPdfPoints().add(margin.top.toPdfPoints())

range(0, targetPagesCount).forEach(pageIndex => {
const page = pdfWriter.createPage.apply(pdfWriter, targetMediaBox)
Expand Down
5 changes: 2 additions & 3 deletions src/puppeteer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ export const mkSizedPdf = async (
margin: PrintMargin = PrintMargin.ofZero(),
) => {
await page.setContent(html)
await page.emulateMedia('screen')
const pdfBuffer = await page.pdf({
width: size.width.toString(),
height: size.height.toString(),
Expand All @@ -50,13 +49,13 @@ export const calcContentSize = async (
page: puppeteer.Page,
) => {
const contentViewPort = {
width: Math.ceil(
width: Math.floor(
pageSize.width
.subtract(margin.left)
.subtract(margin.right)
.toPixels()._n,
),
height: Math.ceil(pageSize.height.toPixels()._n),
height: Math.floor(pageSize.height.toPixels()._n),
}

await page.setViewport(contentViewPort)
Expand Down

0 comments on commit d20d56f

Please sign in to comment.