How to get pdf data in pdfkit without saving it to file - node.js

I am using pdfkit in nodejs to create pdfs. Right now, to get the data from pdfDocument, I first write it to a file using 'fs' and then read back from it.
I want to be able to use the data directly from pdfDocument object and send it as a response. How can I do that?

Each pdfDocument is a stream. You can basically pipe it to the response like this:
require('http').createserver(function (request, response) {
var pdfdocument = require('pdfkit'),
pdfdocument = new pdfdocument();
pdfdocument.text('wassup');
pdfdocument.pipe(response);
pdfdocument.end()
}).listen(1999);

Related

Save file from url base64 data to pdf

I am making a react app where I have a field that allows users to upload PDF files.
I have successfuly uploaded and sent the files as base64 string to the server and I do receive it, however I am having trouble with saving the file back to pdf, here is what I have tried:
const fs = require("fs");
const invoice = { fileData: "data:application/pdf;base64,JVBERi0xLjandtherestofthedatastring..." };
const invoiceFileContents = new Buffer.from(invoice.fileData, "base64");
fs.writeFileSync(__dirname + "invoicetest.pdf", invoiceFileContents);
This does create a pdf file, but I am unable to open it, Adobe says its broken.
I managed to solve it, the appended string infront of the whole data string data:application/pdf;base64, should be trimmed:
const invoiceFileContents = new Buffer.from(
invoice.fileData.substring(invoice.fileData.indexOf("base64") + 7),
"base64"
);

Convert a file stream to a file

I have got an API that responds with audio/video files in forms of stream.
For e.g. a typical response looks like this:
data:audio/mpeg;base64,GkXfo59ChoEBQveBA...
I use axios to call this API and get the raw stream data successfully. How do I convert this data into an usable file and also make this downloadable from the front-end?
P.S. Using React for the front end.
You can create an anchor element, add download attribute and take the data as href. For example:
<a download='hello-world.txt' href="data:text/plain;base64,SGVsbG8gd29ybGQ=">Download Data</a>
This trick also works:
const downloadData = (filename, dataURI) => {
var a = document.createElement('a')
a.setAttribute('href', dataURI)
a.setAttribute('download', filename)
a.click()
a.remove()
}
downloadData("hello-world", "data:text/plain;base64,SGVsbG8gd29ybGQ=")

Using expressjs, is there a way to use mammoth to not use a path?

As the question states, is there a way to use mammoth so that it doesn’t require writing to disk? I see the following package:
https://www.npmjs.com/package/mammoth
var mammoth = require("mammoth");
mammoth.convertToHtml({path: "path/to/document.docx"})
.then(function(result){
var html = result.value; // The generated HTML
var messages = result.messages; // Any messages, such as warnings during conversion
})
.done();
In the mammoth document, the first parameter of convertToHtml function is input, with input is an object describing the source document. On node.js, they supported {path: path} and {buffer: buffer} (or {arrayBuffer: arrayBuffer}).
You can convert the uploaded file to a buffer then push the buffer to convertToHtml function.

upload generated pdf without temporarily writing any file

I want to upload pdf file created by pdfmake to remote server. For that I am using following code roughly.
const doc = printer.createPdfKitDocument(docDefinition);
doc.pipe(fs.createWriteStream(filename))
var form = new FormData();
form.append("file", fs.createReadStream(filename));
let response=await axios.post(url, form, {headers: {
...form.getHeaders(),
}});
But issue with above approach is it requires to create file locally. I want to avoid that and want to take output from pdfmake and send it directly to server. How can I do that ?

Send base64 image using axios in nodejs

I am receiving a base64 encoded image from the client (as a screenshot) and would like to upload it to another server using multipart encoding
var base64Encoded="iVBORw0KGgoAAAANSUhEUgAAAAoAAABkCAYAAAC/zKGXAAAAK0lEQVR42u3KMQ0AAAgDsOFfJwcusMBL0t6tSToHJYqiKIqiKIqiKIri57hqIbTd/KhOmQAAAABJRU5ErkJggg==";
const x =Axios({url:"https://slack.com/api/files.upload",method:"POST", data:{title:"Hello", file: <INSERT HERE>, filetype:"png", channel: "testchannel"},headers:{Authorization: authorization,'Content-Type': 'multipart/form-data'}});
I've tried a lot here
Converting it to a buffer
var buffer = Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAoAAABkCAYAAAC/zKGXAAAAK0lEQVR42u3KMQ0AAAgDsOFfJwcusMBL0t6tSToHJYqiKIqiKIqiKIri57hqIbTd/KhOmQAAAABJRU5ErkJggg==", 'base64');
Converting the buffer into a readable stream
var buffer = Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAoAAABkCAYAAAC/zKGXAAAAK0lEQVR42u3KMQ0AAAgDsOFfJwcusMBL0t6tSToHJYqiKIqiKIqiKIri57hqIbTd/KhOmQAAAABJRU5ErkJggg==", 'base64');
console.log(buffer);
const readable = new Readable();
readable._read = function(){};
readable.push(buffer)
readable.push(null)
None of these seem to work. Slack API simply gives me a invalid form data response
It works if i upload via postman
PS: I have to send axios request using the nodejs server, not browser

Resources