HTML to PDF with Node.js and Electron.js - node.js

Here are the relevant code.
let Name = moment().unix() + ".pdf";
var html = fs.readFileSync('./test/businesscard.html', 'utf8');
let filename = "C:\\App\\Register\\pdf\\" + Name;
pdf.create(html, options).toFile(filename, function (err, response) {
if (err) {
res.status(403).json({
message: 'error'
})
} else {
res.status(200).json({
message: 'success'
})
}
}
it's working fine on dev version and create PDF file. But when i create a
electron build-pack, the pdf file not generated.
If any solution is available then it will be a big help

You should use an absolute path for packaged application by using app.getAppPath().
Remplace this line
var html = fs.readFileSync('./test/businesscard.html', 'utf8');
By this
var html = fs.readFileSync(path.join(app.getAppPath(), '/test/businesscard.html', 'utf8'));
And not forgot to add
const path = require('path')
const app = require('electron').remote.app

Related

Is there a way to get a data from a pdf file and interact it for a web page search? [duplicate]

I have a scenario to automate the PDF contents. How to retrieve the content of the PDF file in nodejs.
I am completely blocked for this. Although there are few posts on pdf2jsona and jsonreader but those are not working for me. Any help will be appreciated for the same.
var pdfParser = new PDFParser();
fs.readFile(pdfFilePath, function(err, pdfBuffer) {
pdfParser.parseBuffer(pdfBuffer);
}, function(pdfBuffer){
pdfParser.parseBuffer(pdfBuffer);
})
Error: Invalid parameter array, need either .data or .url
at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:445:3)
const fs = require("fs");
const PdfReader = require('pdfreader').PdfReader;
fs.readFile("E://file streaming in node js//demo//read.pdf", (err, pdfBuffer) => {
// pdfBuffer contains the file content
new PdfReader().parseBuffer(pdfBuffer, function(err, item){
if (err)
callback(err);
else if (!item)
callback();
else if (item.text)
console.log(item.text);
});
});
I found the answer and it's working perfectly. Install fs and pdf2json by running the below commands.
npm install pdf2json and npm install fs
var fs = require('fs');
var PDFParser = require('pdf2json');
var path = osHomedir();
var homepath = path.replace(new RegExp('\\' + path.sep, 'g'), '/');
var pdfFilePath = homepath + '/Downloads/' + 'filename.pdf';
if (fs.existsSync(pdfFilePath)) {
//Read the content of the pdf from the downloaded path
var pdfParser = new PDFParser(browser, 1);
pdfParser.on("pdfParser_dataError", function (errData) {
console.error(errData.parserError)
});
pdfParser.on("pdfParser_dataReady", function (pdfData) {
//console.log('here is the content: '+pdfParser.getRawTextContent());
browser.assert.ok(pdfParser.getRawTextContent().indexOf(textToVerify) > -1);
});
pdfParser.loadPDF(pdfFilePath);
} else {
console.log('OOPs file not present in the downloaded folder');
//Throw an error if the file is not found in the path mentioned
browser.assert.ok(fs.existsSync(pdfFilePath));
}

how to pass the value dynamically to href in mail template using nodejs

View Report
This is how my html template look like, whereas my nodejs code is
templateContent = fs.readFileSync(templatePath, "utf8");
templateContent = templateContent.replace("##ownername##", ownerObject.ownerName);
templateContent = templateContent.replace("##link##", req.body.details.pdf.pdfUrl);
I got the solution for this. Passing the tag with the node.js file can solve this.
Example:
var link = "<a href='" +req.body.details.pdf.pdfUrl+ "'>Click Here</a>";
templateContent = fs.readFileSync(templatePath, "utf8");
templateContent = templateContent.replace("##ownername##", ownerObject.ownerName);
templateContent = templateContent.replace("##link##", link);
You can also you email-templates-v2 for rendering mail templates.
const { EmailTemplate } = require('email-templates-v2');
const templateDir = path.join(__dirname, '../../../templates', 'template-name');
const template = new EmailTemplate(templateDir);
return new Promise((resolve, reject) => {
template.render({'link':'http://1.com'}, (err, result) => {
if (!err) {
const { html } = result;
resolve(html);
} else {
logger.error(err);
reject(err);
}
});
});
create templates folder with template-name in folder.
templates
email-verification
html.ejs
html.ejs
link

Error: PDFDocument: stream must have data

I am using pdf.js to parse pdf files. First I am uploading the file and then trying to parse that file.I am passing the url to parse function to read it in PDFJS.getDocument(url)
If I don't use the upload part and hardcode the URL of the pdf file it works.
Code :
var parse = function(payload,callback){
var data = payload;
if(data.file){
var name = data.file.hapi.filename;
var ext = name.split('.');
var extension = ext[1];
if(extension == "pdf"){
var path = __dirname + "/uploads/" + name;
checkFileExist();
var file = fs.createWriteStream(path);
file.on('error', function (err) {
console.error(err)
});
data.file.pipe(file);
var fileName = data.file.hapi.filename;
console.log(fileName);
var fileAbsolutepath = __dirname + "/uploads/" + fileName ;
console.log(fileAbsolutepath);
var parser = script.pdfParser(fileAbsolutepath,function(err,resp){
if(err){
callback(err);
}
else {
callback(resp);
}
})
callback(JSON.stringify(fileName));
}
else{
console.log("Invalid fileType");
callback(JSON.stringify("Invalid FileType"));
}
}
}
var checkFileExist = function() {
var path = __dirname + '/uploads';
fs.exists(path, function(exists) {
if (exists === false) fs.mkdirSync(path);
});
};
exports.pdfParser = function(url,callback){
PDFJS.workerSrc = 'pdf.worker.js';
PDFJS.getDocument(url).then(function (pdf) {
var pdfDocument = pdf;
}}
The file is uploaded properly with expected file size in uploads folder still I get error : "Error: PDFDocument: stream must have data"
To parse files with pdf.js, rather than loading the file with PDFJS.getDocument, try converting the pdf file to an arrayBuffer or Uint8Array, and use that to create a new LocalPdfManager object. Then you can call the LocalPdfManager's methods directly to parse the pdf.
Something like this:
import { LocalPdfManager } from 'pdfjs-dist/lib/core/pdf_manager';
pdfManager = new LocalPdfManager(1, arrayBuffer, '', {}, '');
// parameters = (docId, data, password, evaluatorOptions, docBaseUrl)
pdfManager.ensureDoc('parseStartXRef', []); // [] = arguments
pdfManager.ensureDoc('parse', false); // false = recoveryMode
pdfManager.ensureDoc('numPages');
pdfManager.ensureDoc('fingerprint');
Then look at pdfManager.pdfDocument for the parsed pdf data.
For example, the main "/Catalog" entry will be in pdfManager.pdfDocument.catalog.catDict.
I've used this method to successfully parse and modify pdf files locally in a browser. I haven't tried it on a server with node.js, but I expect it should work the same.

On which format send file to save it on gridfs?

Hy every one,
Please , i 'm study on a project using nodeJS, and i would like to know , in which format my node client must send the file to the server ( is it in base64 format or else ?).
my client is :
//client.js
$('#file').on('change', function(e){
encode64(this);
});
function encode64(input) {
if (input.files){
chap.emit('test', { "test" : input.files[0] });
var FR= new FileReader();
FR.readAsDataURL(input.files[0]);
FR.onload = function(e) {
chap.emit('test', { "test" : e.target.result } );
}
}
}
My server side is :
socket.on('test', function(e){
var gs = new gridStore(db, e.test,"w");
gs.writeFile(new Buffer(e.test,"base64"), function(err,calb){
if (!err)
console.log('bien passe');
else
console.log('erreur');
});
});
But this doesn't work , i get this error :
TypeError: Bad argument
at Object.fs.fstat (fs.js:667:11)
Any one could help me ?
Normally this is how you store into gridFs . I have used it to store files. hope it works.
fs = require('fs'),
var gfs = require('gridfs-stream');
var form = new multiparty.Form();
form.parse(req, function (err, fields, files) {
var file = files.file[0];
var filename = file.originalFilename; //filename
var contentType = file.headers['content-type'];
console.log(files)
var tmpPath = file.path ;// temporary path
var writestream = gfs.createWriteStream({filename: fileName});
// open a stream to the temporary file created by Express...
fs.createReadStream(tmpPath)
// and pipe it to gfs
.pipe(writestream);
writestream.on('close', function (file) {
// do something with `file`
res.send(value);
});
})

Send PDF file from AngularJS to NodeJS

i need to send a PDF file from angularjs client to NodeJS service.
I did the angularjs service, and when i receive the file its a string like this:
%PDF-1.3
3 0 obj
<</Type /Page
/Parent 1 0 R
/Reso
How can i reconvert this string to PDF in NodeJS?
This is the client code:
var sendByEmail = function () {
$scope.generatingPdf = true;
$('#budget').show();
var pdf = new JsPDF('p', 'pt', 'letter');
var source = $('#budget')[0];
pdf.addHTML(source, 0, 0, function () {
var resultPdf = pdf.output();
BillService.sendByEmail("rbrlnx#gmail.com", resultPdf).then(function () {
});
$('#budget').hide();
});
};
var sendByEmail = function (email, file) {
var deferred = $q.defer();
var data = {
email: email,
file: file
};
BillService.sendByEmail(data, function (result) {
deferred.resolve(result);
}, function () {
deferred.reject();
});
return deferred.promise;
};
The server code controller its empty:
var sendByEmail = function (req, res, next) {
var file = req.body.file;
};
I experimented with this a while ago, and I came up with this. It's not production ready by a long shot maybe you find it useful. It's free of front end libraries (except Angular ofcourse), but assumes you're using Express 4x and body-parser.
The result:
In the browser:
On the server:
What you're seeing:
You're seeing a tiny node server, serving static index.html and angular files, and a POST route receiving a PDF in base64 as delivered by the HTML FileReader API, and saves it to disk.
Instead of saving to disk, you can send it as an email attachment. See for instance here or here for some info on that.
The example below assumes uploading a PDF by a user through a file input, but the idea is the same for all other ways of sending a document to your back end system. The most important thing is to send the pdf data as BASE64, because this is the format that most file writers and email packages use (as opposed to straight up binary for instance..). This also goes for images, documents etc.
How did I do that:
In your HTML:
<div pdfs>Your browser doesn't support File API.</div>
A directive called pdfs:
myApp.directive('pdfs', ['upload', function(upload) {
return {
replace: true,
scope: function() {
files = null;
},
template: '<input id="files" type="file">',
link: function(scope,element) {
element.bind('change', function(evt) {
scope.$apply(function() {
scope.files = evt.target.files;
});
});
},
controller: function($scope, $attrs) {
$scope.$watch('files', function(files) {
//upload.put(files)
if(typeof files !== 'undefined' && files.length > 0) {
for(var i = 0; i<files.length;i++) {
readFile(files[i])
}
}
}, true);
function readFile(file) {
var reader = new FileReader();
reader.addEventListener("loadend", function(evt) {
upload.post({name: file.name, data: reader.result})
})
if(reader.type = 'application/pdf') {
reader.readAsDataURL(file);
}
}
}
}
}]);
A tiny service:
myApp.service('upload', function($http) {
this.post = function(file) {
$http.post('/pdf', file);
}
});
And a node server:
var express = require('express');
var bodyParser = require('body-parser')
var fs = require("fs");
var app = express();
app.use(express.static('.'));
app.use( bodyParser.json({limit: '1mb'}) );
app.post('/pdf', function(req, res){
var name = req.body.name;
var pdf = req.body.data;
var pdf = pdf.replace('data:application/pdf;base64,', '');
res.send('received');
fs.writeFile(name, pdf, 'base64', function(err) {
console.log(err);
});
});
var server = app.listen(3000, function() {
console.log('Listening on port %d', server.address().port);
});

Resources