Search code examples
node.jsfilepdfupload

node.js receive PDF file and print


I try to create a endpoint API which can:

  1. receive a PDF docuent comming from a standard html form
  2. stores the pdf file
  3. does a print out with pdf-to-printer
  4. deletes the temporary pdf file from point 2

Thats the main structure at the moment - i cant get the file post solved...

import express from "express";
import ptp from "pdf-to-printer";
import fs from "fs";
import path from "path";

const app = express();
const port = 3000;

ptp.getPrinters().then(console.log);

app.post('', express.raw({ type: 'application/pdf' }), async(req, res) => {

    const options = {
        printer: "Microsoft Print to PDF"
        //pages: "1-3,5",
        //scale: "fit",
      };

    /*if (req.query.printer) {
        options.printer = req.query.printer;
    }*/
    const tmpFilePath = path.join(`./tmp/${Math.random().toString(36).substr(7)}.pdf`);

    fs.writeFileSync(tmpFilePath, req.body, 'binary');
    await ptp.print(tmpFilePath, options);
    fs.unlinkSync(tmpFilePath);

    res.status(204);
    res.send();
});

app.listen(port, () => {
    console.log(`PDF Printing Service listening on port ${port}`)
});

My "File Upload" is just a regular HTML Form - but I cant get it working


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>PDF Printer</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <form action="http://localhost:3000" method="post" enctype="multipart/form-data">
        <input type="file" name="someExpressFiles" id="myFile" size="500" />
        <input type="text" name="title" />
        <br />
        <input type="submit" value="Upload" />
        </form>
  </body>
</html>

Solution

  • to be fair i am also new but you can try this with multer

    npm install multer
    

    we're using req.file.path to get the path to the uploaded PDF file, which is stored temporarily by multer. This should resolve the "TypeError [ERR_INVALID_ARG_TYPE]" issue you were encountering

    import express from "express";
    import ptp from "pdf-to-printer";
    import multer from "multer";
    import path from "path";
    import fs from "fs/promises";
    
    const app = express();
    const port = 3000;
    
    app.use(express.urlencoded({ extended: true }));
    app.use(express.json());
    
    const storage = multer.diskStorage({
      destination: "./tmp",
      filename: (req, file, cb) => {
        const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9);
        cb(null, "pdf_" + uniqueSuffix + path.extname(file.originalname));
      }
    });
    
    const upload = multer({ storage });
    
    app.post('/print', upload.single("pdfFile"), async (req, res) => {
      try {
        const pdfFilePath = req.file.path;
        const options = {
          printer: "Microsoft Print to PDF"
          // Other print options here
        };
    
        await ptp.print(pdfFilePath, options);
        await fs.unlink(pdfFilePath);
    
        res.status(200).send("PDF printed successfully.");
      } catch (error) {
        console.error(error);
        res.status(500).send("Error printing PDF.");
      }
    });
    
    app.listen(port, () => {
      console.log(`PDF Printing Service listening on port ${port}`);
    });