PDFMake Base64 generates malformed document - javascript

I'm using PDFMake to generate some PDF reports on client side.
When I specify the definition for document and pass it to createPdf(DEFINITION_HERE) I get my PDF and it looks nice and shiny. But I'm saving it in the DB as Base64 encoded string and when I try to reopen it with data URI (ie: data:application/pdf;base64,JVBER...) the document is completely malformed.
My DB call looks like this:
await pdfFile.getDataUrl(async (result: string) => {
await myServiceLayer.generatePdfReport(result, fileName, creator);
});
Anyone else had this issue with PDFMake library? Any ideas on what could be the cause of this?

OK, so after trying different things and debugging left and right, I stumbled upon this:
https://github.com/bpampuch/pdfmake/issues/318
So I removed call to .download() on my PDF file and checked for Base64 again, now it had correct value and file looks as it should.
So in a nutshell, if we call multiple methods on PDFMake, usually something will get messed up.
I had my .download() call just before my .getBase64() as I wanted to first download the file for the user and then also store it in DB as Base64, as .download() happened .getBase64() kept on giving me Base64 output which resulted in malformed PDF file.

Related

Cordova fileWriter.write() doesn't work with blobs

In the official documentation and many other solutions posted online, the following code is supposed to be the way of writing data to a file in Cordova
function writeFile(fileEntry, dataObj) {
fileEntry.createWriter(function (fileWriter) {
fileWriter.write(dataObj);
});
}
writeFile(someFileEntry, blob);
In the documentation, they explicitly shown that a blob can be passed as the "dataObj", but whenever I passed a blob as "dataObj", the resulting file only has 2 bytes of data. After inspecting the file, I found that the contents of the file only contain a single string
{}
hence the 2 bytes.
I've tried passing a string as the "dataObj", and the contents of the resulting file was the exact same string, so string works I guess? But the data I'm wishing to write to a file is a blob that contains video data recorded from a canvas, so either I'll have to
somehow convert the the video blob into a string and write the string into the file
somehow fix the "fileWriter.write" function
But I've gone nowhere with these solutions. I've tried "blob.text()" or using a "fileReader" to get the contents of the blob as a string, but the resulting file is always broken. And fixing the "fileWriter.write" function is way out of my depth. Can someone help me out on this?
I am having the same issue. I think it might have something to do with the following as stated on the cordova-plugin-file docs:
But I find that odd since the examples all use FileWriter.write(blob) but it says that the platforms do not support that function.

Reading local BSON file in Javascript

I have an HTML 5 game. I'm using webpack/typescript for development.
There is some data I have which I was including by using require like the following
const dataJson = require('scripts/data/data.json');
I would like to do the equivalent, except with bson. I tried the naive approach of doing something like this
const dataJson = require('scripts/data/data.bson');
but this of course fails since there is no loader (won't compile with currently no loaders are configured to process this file.).
I'd like to then include the file locally, load the file and then deserialize the bson. Or I'd like to embed the bson like when using require. This is some tool generated data, so it will be in a data file.
I haven't been able to figure it out. I've tried the following. But this results in the result containing either the bits of File or what looks like the content type (if done as readAsDataURL).
What I have tried
const file = new File(['data'], 'assets/data.bson', { type: 'application/bson' });
const reader = new FileReader();
reader.onload=(theFile) => {
if (theFile.target) {
console.log(theFile.target.result);
}
} ;
reader.readAsDataURL(file);
//reader.readAsBinaryString(file);
What is the correct method to load a local binary file? Presumably, once I have the data, I can just call deserialize from the bson package.
Okay, I'm adding some corrections here.
My method to read the files is wrong. I know understand File will actually create a file. So when this is passed to FileReader it gets the value of the both bits passed in.
I have since discovered I can get the local files 2 ways. I can use XMLHttpRequest as well as the raw-loader loader.
However once I do this. I cannot seem to convert the contents into JSON using bson. Any variant of deserialize, serialize, parse, or stringify has some issue.
Does anyone happen to have the correct method to convert the BSON contents into either a Javascript Object?
Note that the BSON is generated from python using pymongo. My code to generate the BSON is the following.
with open(args.output_bson, 'wb') as fp:
encoded = bson.encode(data_meta.to_dict())
fp.write(encoded)
to_dict is a dictionary. I output both the JSON (using json) and BSON.
I also tested the file with bsondump and it does indeed convert to JSON. So it does appear the file I've loaded is valid.
you can use bson
then call:
BSON.deserialize(theFile.target.result);

AWS S3 getting Not a valid bitmap file

I have been struggling with this for a while and I am going to provide you with as much information as possible (some maybe irrelevant) because I am completely stuck. I am using Ionic and I would like to be able to take a picture with my phone and upload it to an AWS S3 bucket. I used Cordova camera to accomplish this.
As far as I know; these pictures come out in a large base64 string and I have to convert it to a Blob, convert it to a File object then upload that file object into AWS. However, when I do this it always uploads it as something other than an image. Whenever I open it I get an error saying:
"Not a valid bitmap file. its format is not currently supported."
https://s3.amazonaws.com/mng-moment/moment/PA/40.008446_-75.26046_1502414224619.jpg
Here is an example of a WORKING one (This used to work it somehow broke):
https://s3.amazonaws.com/mng-moment/bestMoments/40.008446_-75.26046_1499659199473.jpg
I tried to open each one in a text editor to see what is going on. For the first one (The broken one) I get this:
When I try to open the working one in a text editor I get this:
Now it seems like a conversion problem but I think I am converting it correctly.
Here is the code I am using to upload (You can see the console.logs later on the post):
core.js
awsServices.js
If you look at the comments in the code I labeled some of the console logs. I will display them here for more information:
A - (uploadToAWS):
B - (awsServices.upload):
This is how I convert the dataURI to a Blob (Called in uplpoadToAWS - The first screenshot):
This is what gets passed into the 'dataURI' parameter in the code right above:
If there is any more information please let me know. I've been scratching my head at this for a while. Any help is appreciated. Thanks!
As stated in MDN File API:
A File object is a specific kind of a Blob, and can be used in any context that a Blob can. In particular, FileReader, URL.createObjectURL(), createImageBitmap(), and XMLHttpRequest.send() accept both Blobs and Files.
So, i think your problem reside in your uploadToAws function because you first create a Blob and then use the Blob to create a File, when I think you simply should initialize the File object with the byte array returned by dataURItoBlob since the File object is in fact already a Blob object.

How do you check whether a CSV file is corrupted in PHP and/or Javascript?

I'm making an HTML5/jQuery/PHP app which involves uploading CSV files (via a drag and drop), and processing them to a MySQL database. So far, I can upload the files, and I know how to read them into a database.
My question: I am wondering if it is possible to detect whether a CSV file is in a corrupted format by PHP or Javascript/jQuery? For example, I can rename somefile.png (an image) to somefile.csv, and it still gets uploaded. If I open up the renamed file in Notepad++, all I see is garbage, which is expected.
I would like to do this on the clientside, so I can alert the user (via JQuery) whether the file is in a corrupted format. I'd also like to check on the serverside (via PHP) before I start iterating over each CSV file for db processing.
My first thoughts would be to use regular expressions, but I am unsure how to make ones for this particular problem. I know the basics of regular expressions, but haven't really used them in advanced settings before.
First of all you should check content-type of picked file, it should be "text/csv". At the server-side you can check file via fgetscsv PHP function (http://php.net/manual/function.fgetcsv.php) (catch null or false on error)
You don't want to be validating it if you're going to be reading it right after. Just read it in and catch any errors as you read. That way you come to know whether file is valid or corrupt.

javascript sendfile binary data to web service

At work we are trying to upload files from a web page to a web service using html 5/javascript in the browser end and C# in the web service. But have some trouble with encoding of some sort.
As for the javascript we get the file's binary data with help from a FileReader.
var file = ... // gets the file from an input
var fileReader = new FileReader();
fileReader.onload = dataRecieved;
fileReader.readAsBinaryString(file);
function dataRecieved() {
// Here we do a normal jquery ajax post with the file data (fileReader.result).
}
Wy we are posting the data manually and not with help from XmlHttpRequest (or similar) is for easier overall posting to our web service from different parts of the web page (it's wrapped in a function). But that doesn't seem to be the problem.
The code in the Web Service looks like this
[WebMethod]
public string SaveFileValueFieldValue(string value)
{
System.Text.UnicodeEncoding encoder = new UnicodeEncoding();
byte[] bytes = encoder.GetBytes(value);
// Saves file from bytes here...
}
All works well, and the data seems to be normal, but when trying to open a file (an image as example) it cannot be opened. Very basic text files seems to turn out okay. But if I upload a "binary" file like an image and then open both the original and the uploaded version in a normal text editor as notepad to see what differs, it seems to be wrong with only a few "invisible" characters and something that displays as a new line a few bytes in from from the start.
So basicly, the file seems to encode just a few bytes wrong somewhere in the conversions.
I've also tried to create an int array in javascript from the data, and then again transformed to a byte[] in the web service, with the exact same problem. If I try to convert with anything else than unicode (like UTF-8), the data turns out completly different from the original, so I think om on the right track here, but with something slightly wrong.
The request itself is text, so binary data is lost if you send the wrong enc-type.
What you can do is encode the binary to base64 and decode it on the other side.
To change the enc-type to multi-part/mixed and set boundaries (just like an e-mail or something) you'd have to assemble the request yourself.

Categories

Resources