DEV Community

Cover image for pdfmake Server Side Outputs
Helen Kwok
Helen Kwok

Posted on

pdfmake Server Side Outputs

While the documentation of pdfmake version 0.3 covers the most critical features and functionalities for PDF generation, it is under development and therefore not everything has been included.

There is an example in the repository, and it shows a way to generate a PDF from the server, convert it into a Data URL and serve it as an API with ‘content-type’ = ‘application/pdf’. As long as the front end can consume the API and make use of the Data URL, it should be pretty straightforward. However, this may not be an application if you want to download the PDF from an iOS Safari browser (there is a new response after 11 years).

Actually, pdfmake provides multiple output format (stream, buffer and Base64) and you can see it from the repository. The code is shown below:

/* pdfmake/src/OutputDocument.js */

class OutputDocument {

    /**
     * @param {Promise<object>} pdfDocumentPromise
     */
    constructor(pdfDocumentPromise) {
        this.bufferSize = 1073741824;
        this.pdfDocumentPromise = pdfDocumentPromise;
        this.bufferPromise = null;
    }

    /**
     * @returns {Promise<object>}
     */
    getStream() {
        return this.pdfDocumentPromise;
    }

    /**
     * @returns {Promise<Buffer>}
     */
    getBuffer() {
        if (this.bufferPromise === null) {
            this.bufferPromise = new Promise((resolve, reject) => {
                this.getStream().then(stream => {

                    let chunks = [];
                    let result;
                    stream.on('readable', () => {
                        let chunk;
                        while ((chunk = stream.read(this.bufferSize)) !== null) {
                            chunks.push(chunk);
                        }
                    });
                    stream.on('end', () => {
                        result = Buffer.concat(chunks);
                        resolve(result);
                    });
                    stream.end();

                }, result => {
                    reject(result);
                });
            });
        }

        return this.bufferPromise;
    }

    /**
     * @returns {Promise<string>}
     */
    getBase64() {
        return new Promise((resolve, reject) => {
            this.getBuffer().then(buffer => {
                resolve(buffer.toString('base64'));
            }, result => {
                reject(result);
            });
        });
    }

    /**
     * @returns {Promise<string>}
     */
    getDataUrl() {
        return new Promise((resolve, reject) => {
            this.getBase64().then(data => {
                resolve('data:application/pdf;base64,' + data);
            }, result => {
                reject(result);
            });
        });
    }

}

export default OutputDocument;
Enter fullscreen mode Exit fullscreen mode

Apart from getDataUrl, we can also use getStream, getBuffer and getBase64. This will make things easier if you want to use Blob(a file-like object of immutable, raw data) to make things smaller. Here is an explanation of why to use Blob in browsers.

Top comments (0)