HTML to PDF Action - NodeJS & PHP [Open Source]

The link shared above talks about PUPPETEER_EXPERIMENTAL_CHROMIUM_MAC_ARM - maybe try that flag.
ENV flag says to NOT install Chromium - which could be the problem.

Sorry but I don’t have an M1 to test.

For me it looks like the error I get has nothing to do with the advice/fixes in that link. This seems to be more of the help needed:

just want to keep on documenting this for M1 mac running docker. The key is to run puppeteer with chromium(or any other browser) install since amd64 version of chrome does not work on arm processors.

I am following and trying to apply code from this sample docker file:

After a day of reading up as much as I can with regards to Puppeteer + Docker + M1 Arm Processor Mac and Chromium, I think I might be close to a solution, but cannot get better than this. This is my current error when running a pdf create action in the browser:

{"status":"500","message":"Failed to parse parameter value: undefinedmm","stack":"Error: Failed to parse parameter value: undefinedmm\n at assert (/opt/node_app/node_modules/puppeteer/lib/cjs/puppeteer/util/assert.js:28:15)\n at convertPrintParameterToInches (/opt/node_app/node_modules/puppeteer/lib/cjs/puppeteer/common/Page.js:2677:32)\n at CDPPage.createPDFStream (/opt/node_app/node_modules/puppeteer/lib/cjs/puppeteer/common/Page.js:1969:27)\n at CDPPage.pdf (/opt/node_app/node_modules/puppeteer/lib/cjs/puppeteer/common/Page.js:2006:37)\n at App.exports.ConvertToPDF (/opt/node_app/extensions/server_connect/modules/HtmlToPDF.js:95:16)\n at processTicksAndRejections (node:internal/process/task_queues:96:5)\n at async App._exec (/opt/node_app/lib/core/app.js:491:30)\n at async App._exec (/opt/node_app/lib/core/app.js:458:17)\n at async App.exec (/opt/node_app/lib/core/app.js:427:9)\n at async App.exec (/opt/node_app/lib/modules/core.js:228:13)"}

This is the change I made to the original Html2Pdf.js:

const puppeteer = require('puppeteer');
const fs = require('fs');

(async () => {
    await puppeteer.launch({
        executablePath: '/usr/bin/chromium',
        headless: true,
        args: [
            '--no-sandbox',
            '--disable-setuid-sandbox'
        ]
    });
})();

exports.ConvertToPDF = async function (options) { 

...

And this is the content of my docker file:

    FROM node:16-bullseye

    ARG NODE_ENV=production

    ENV NODE_ENV $NODE_ENV

    ARG PORT=3000

    ENV PORT $PORT

    EXPOSE $PORT

    ENV PATH /opt/node_app/node_modules/.bin:$PATH

    ENV NODE_ENV development

    WORKDIR /opt/node_app

    COPY index.js .

    COPY package.json .

    RUN apt-get update \

    && apt-get install -y chromium \

    fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 \

    --no-install-recommends

    COPY --chown=node package.json .

    COPY --chown=node package-lock.json .

    ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true

    ENV PUPPETEER_EXECUTABLE_PATH /usr/bin/chromium

    RUN npm install --no-optional --no-package-lock

    CMD [ "nodemon", "./index.js" ]

This is an extension issue. In some Wappler update, null values started showing up as undefined.
So what you are seeing is probably footer or margin value, which is undefinedmm instead of being 0mm.
Try setting all values to 0 or whatever you need to get rid of this.

1 Like

Thanks for checking in. I did try that but no change in error:

Manually filling in default values has no change, I noticed this while developing an extension. Use 1 mm instead

2 Likes

That did the trick in running the action without errors:

I just do not see the folder populated with a test.pdf file. It might be my path that is wrong or do you need the whole url and not just with reference to the local file structure?

Here is my file structure:

What would my path be to add the file to “reports” folder?

It seems the initial dot on your folder name was striped away, try removing the ./ completely

1 Like

As suggested above, folder name just needs to be reports.
It will create the folder in the root of the app automatically.

// pdf file path
    var filePath = __dirname + '/../../../' + options.folderName + '/' + options.fileName + '.pdf';

    var folderPath = __dirname + '/../../../' + options.folderName;
    if (!fs.existsSync(folderPath)) {
        fs.mkdirSync(folderPath);
    }
1 Like

Unfortunately nothing happens when I change it to just folder name.

Any way I can troubleshoot?

You can write console.log in the JS file… and see the logs printed in the webserver logs of your docker ocntainer, or in the local server logs if you are running local NodeJS.
Also, you can try putting folder name as /reports or /public/reports.

1 Like

public/reports was the winner! Thanks so much! I really had little hope and then it just worked. Hopefully my documenting everything above will help the Docker Mac M1 people in future

3 Likes

Thanks @sid for this cool extension. For me the demo project was an instant win. Worked straight out of the box. Only thing I needed to do to get it running in my own project was copy the extensions folder, put puppeteer in de package file and npm puppeteer. Copied your server action and page to generate the pdf, as well. Worked flawlessly.

Adding bootstrap was as easy as pasting

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

to the html in the server action.

Thanks!

2 Likes

:slight_smile:
I have updated the extension fixing some bugs and other stuff.
Hopefully will update it on Git tomorrow.

2 Likes

Hi @sid,

I’m going to install this over the weekend. Just checking the files and instruction are up-to-date before doing so ?

Thanks

Damn. I keep forgetting to do this. Will update the post once I deploy it. Today or tomorrow. This time I will try my best to get it done. :sweat_smile:

Thanks @sid

I’ll keep an eye open for updates over the weekend.

-John

Finally an update to the NodeJS version. Unfortunately, no update for PHP version since it hasn’t been in active use/development.

  • Updated project files to Wappler v5.1.1 and node packages.
  • Added option to set HTML or URL as source for PDF.
  • Added option to replace accents and special chars from output PDF file name.
  • Improved params used to initialize puppeteer instance.
  • Improved handling of default values and fixed bug in footer condition.
  • Added another tab in the UI to generate PDF using URL option for testing.

Download from the repo: https://gitlab.com/wappler-extensions/html-to-pdf-nodejs

3 Likes

Cheers Siddhant. You’re a star

1 Like