node-qpdf
node-qpdf copied to clipboard
[SOLVED] If you use windows os with NodeJs and struggling with node-qpdf
1. Do not even use node-qpdf. Use the real McCoy, ie. qpdf, the executable that node-qpdf is built on. 2. Download qpdf (https://sourceforge.net/projects/qpdf/files/qpdf/10.0.4/qpdf-10.0.4.tar.gz.asc/download) 3. Go into EnvironmentalVariables and create a path to the bin folder of downloaded & extracted qpdf (#2) above.
4. Here is the code and it works! There is extra code for other stuff I was doing, ie gzip, etc, and was too lazy to separate.
const zlib = require('zlib');
const fs = require('fs');
const path = require('path');
const router = require('express').Router();
const multer = require('multer');
const express = require('express');
const app = express();
const uploadDir = path.join(__dirname, '../../imageUploads/');
const uploadPdfDir = path.join(__dirname, '../../pdfUploads/');
const compressDir = path.join(__dirname, '../../compressedImages/');
const MAX_SIZE = 20000000;
app.use(function (err, req, res, next) {
if (err.code === 'LIMIT_FILE_TYPES') {
res.status(422).json({ error: 'Only images are allowed' });
return;
}
if (err.code === 'LIMIT_FILE_SIZE') {
res.status(422).json({ error: `Too large. Max Size is ${MAX_SIZE / 1000}kb` });
}
});
const fileFilter = function (req, file, cb) {
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'application/pdf'];
if (!allowedTypes.includes(file.mimetype)) {
const error = new Error('Wrong file type.');
error.code = 'LIMIT_FILE_TYPES';
return cb(error, false);
}
if (file.size > MAX_SIZE) {
const error = new Error('File too large.');
error.code = 'LIMIT_FILE_SIZE';
return cb(error, false);
}
cb(null, true);
};
const storage = multer.diskStorage({
destination: (req, file, cb) => {
if (file.mimetype.includes('pdf')) {
cb(null, uploadPdfDir);
} else {
cb(null, uploadDir);
}
},
filename: (req, file, cb) => {
const fileName = file.originalname.toLowerCase().split(' ').join('-');
cb(null, fileName);
}
});
function encryptPdf (file, ownerPwd, userPwd) {
const fullFilePath = uploadPdfDir + file.filename;
// this line below works without an NodeJs install to package.json because you set qpdf in your environmental variables
const exec = require('child_process').exec;
// using --replace-input overwrites existing file and encrypts. If you want a new file
// remove --replace-input and put the full path of the new file you want encrypted
const cmd = 'qpdf --encrypt ' + ownerPwd + ' ' + userPwd + ' 40 -- ' + fullFilePath + ' --replace-input';
exec(cmd, function (err) {
if (err) {
console.error('Error occured: ' + err);
} else {
console.log('PDF encrypted :)');
}
});
}
const upload = multer({
storage,
fileFilter,
limits: {
fileSize: MAX_SIZE
}
});
router.route('/uploadCompress/')
.post(upload.single('file'), async (req, res) => {
try {
const destination = `${compressDir}/${req.file.originalname}.gz`;
const fileBuffer = req.file.buffer;
await zlib.gzip(fileBuffer, (err, response) => {
if (err) {
console.log(err);
}
fs.writeFile(path.join(__dirname, destination), response, (err, data) => {
if (err) {
console.log(err);
}
res.download(path.join(__dirname, destination));
});
});
} catch (err) {
console.log(err);
res.json(err);
}
});
router.route('/uploadFiles/')
.post(upload.single('file'), (req, res) => {
res.json({ file: req.file });
});
router.route('/uploadPdfFiles/')
.post(upload.single('file'), (req, res) => {
encryptPdf(req.file, 'ownerPWD', 'userPWD');
res.json({ file: req.file });
});
module.exports = router;