pdftron webviewer - how to save the whole edited pdf to server with php - javascript

I am currently a developing an application that is using a PDFTron webviewer. Is there anyway to save the edited pdf edited with pdftron webviewer to the server?
There is a feature of pdftron that saves annotations to the server, but I need to save the whole pdf with the edits to the server.

You could call the following function from a WebViewer config file to get the PDF data as a blob. Once you have the blob you can refer to one of the many examples online of how to upload a blob to a server.
function uploadPDF() {
var docViewer = readerControl.docViewer;
var options = {
xfdfString: docViewer.getAnnotationManager().exportAnnotations()
};
var doc = docViewer.getDocument();
doc.getFileData(options).then(function(data) {
var arr = new Uint8Array(data);
var blob = new Blob([arr], {
type: 'application/pdf'
});
// upload blob here
});
}

Related

Normalising the fileName in IE11 and creating of a new file in Javscript

I'm trying to upload a file, but i want to normalize it's name fisrt, it works on other browsers, but in IE11, i searched and i found out that this method (normalize) is not supported, so i'm using polyfill unorm. so normalizing works fine now, but we can't change the fileName directly, we need to create a new file. But we can't use new File because it's not supported too. So I used new Blob, but the problem is that i don't get the filename on the server side, it's always blob.
The code for other browsers :
var fileName = file.name.normalize('NFD').replace(/[\u0300-\u036f]/g, "");
var newFile = new File([file], fileName, { type: file.type });
newFile.label = 'FICHIER';
The code for IE11
fileName = unorm.nfd(file.name);
newFile = new Blob([file], { type: file.type });
newFile.label = 'Fichier';
newFile.name= fileName;
To generate the request to the server, i use formdata :
fd = new FormData();
fd.append("id", param);
fd.append(file.label || "uploadedFile", file, file[paramName]);
Can you tell me what should i do to get the filename or if there is another way to do this.
The Blob object doesn't contain the name property, so, we can't change name via the Blob object.
After getting the file data, I suggest you could append a new parameter to log the new file name, then, when submits the form or save the uploaded file, you could send the file data and the new file name to the server.
Besides, here is another thread about upload file using FormData, please refer to it:
Angular File Upload
File Upload using AngularJS

Save a JSON file to server with javascript application

I'm developing a simple Javascript application where the user has some images (stored in my machine) and he is able to annotate them and then save the annotations as a JSON file.
The application is very light and simple and it is not an app server.
However, I need to save those JSON files to the machine that will be behaving as the server.
Since I cannot use Javascript for IO, is there any easy and simple way to save those files without having to implement an app server?
I used Blob to download the files.
function project_save_confirmed(input) {
if ( input.project_name.value !== _onco_settings.project.name ) {
project_set_name(input.project_name.value);
}
// onco project
var _onco_project = { '_onco_settings': _onco_settings,
'_onco_img_metadata': _onco_img_metadata,
'_onco_attributes': _onco_attributes };
var filename = input.project_name.value + '.json';
var data_blob = new Blob( [JSON.stringify(_onco_project)],
{type: 'text/json;charset=utf-8'});
save_data_to_local_file(data_blob, filename);
user_input_default_cancel_handler();
}
function save_data_to_local_file(data, filename) {
var a = document.createElement('a');
a.href = URL.createObjectURL(data);
a.download = filename;
a.click();
}
Any suggestion?
Kind regards!
Copy paste from: Download JSON object as a file from browser
function downloadObjectAsJson(exportObj, exportName){
var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(exportObj));
var downloadAnchorNode = document.createElement('a');
downloadAnchorNode.setAttribute("href", dataStr);
downloadAnchorNode.setAttribute("download", exportName + ".json");
document.body.appendChild(downloadAnchorNode); // required for firefox
downloadAnchorNode.click();
downloadAnchorNode.remove();
}
This I believe accomplishes what you want, just makes sure that the proper headers are set, push it to an <a> tag, then click() it
You can do this in php:
<?php
//notice this will put WHATEVER is in json into file
$filename="config.json";
if (isset($_POST["json"])) {
file_put_contents($filename,$_POST["json"]);
}
?>
then for the JS side:
var fd=new FormData();
fd.append("json", JSON.stringify(_onco_project));
fetch("https://url.com",{method:"POST",body:fd})
Explanation: JS makes a new formdata, and sets "json" to the stringified json, and sends it off to the server. The php server takes this, and puts it directly into $filename. Make sure data is safe before putting it to file, as it will take whatever it is given and put it into your file!

Can you insert a PDF generated by PDFKit into a MongoDB collection?

I'm generating a PDF using the PDFKit library and I would like to insert the generated PDF into a MongoDB collection. On the client side a user should be able to see the list of files in the collection and choose one of these files to download.
As of now I'm saving the PDF in the collection as a Uint8Array and I can then click on the file at the front end to download it.
However, my problem is that the file seems to be corrupt. It will not open in Adobe Reader or in Chrome.
I've tried saving it to the collection with and without PDFKits compression.
Is this possible to do? Or do I have a bad approach to this.
Any help with this would be great and thanks in advance!
Server Side
Most of the code here is based off of this post on the PDFKit GitHub
var doc = new PDFDocument();
var stream = require('stream');
var converter = new stream.PassThrough();
doc.pipe(converter);
var data = [];
converter.on('data', function(chunk) {
data.push(chunk);
});
converter.on('end', Meteor.bindEnvironment( function () {
var buffer = Buffer.concat(data);
PdfFiles.insert({ data:buffer, userID:userId });
}));
// Adding content to the PDF
doc.end();
Client Side
'click .downloadPDF': function (event) {
event.preventDefault();
var file = UserFiles.findOne({userID:Meteor.userId()});
var FileSaver = require('file-saver');
var blob = new Blob(file.data, {type: "application/pdf"});
FileSaver.saveAs(blob, "AwesomePDF");
}
I got the code to work as intended simply by changing:
var blob = new Blob(file.data, {type: "application/pdf"});
to
var blob = new Blob([file.data], {type: "application/pdf"});

Get file type after sending the file from WebRTC

I am using WebRTC to get two clients communicated using peer.js
var peer = new Peer(
{
key: "XXX",
config: {"XXX": [{ url: "XXXXXXX" }]}
});
My main aim is to send file from one client to another. For that I am using following code:
$("#box").on("drop", function(e)
{
e.originalEvent.preventDefault();
var file = e.originalEvent.dataTransfer.files[0];
console.log(file);
connection.send(file);
});
On the receiving end I am using below code:
conn.on("data", function(data)
{
if (data.constructor === ArrayBuffer)
{
var dataView = new Uint8Array(data);
var dataBlob = new Blob([dataView]);
var reader = new window.FileReader();
reader.readAsText(dataBlob);
console.log(reader);
}
}
Now my problem is I want to get the file type so that I can save it in the proper format. I am using download.js to save the file.
It is not possible to get the type from the raw data except there is some file type/hint embedded in the data (e.g. ZIP, PDF). You should create you own protocol to send the filename as well.
What I did is to use the channel's protocol property to set the filename with extension to transfer these type of metadata information.
Note that a few weeks ago sending blobs wasn't fully supported in Chrome (at least in one of my example applications).

Append image file to form data - Cordova/Angular

I am using Anuglar, Ionic and Cordova in my current project, and I'm trying to POST FormData containing an image file to my server. Right now I'm using the cordova camera plugin to return a file path to the image on the device (ex: file://path/to/img). Once I have the file path I want to append the image file to a FormData object using the images file path. Here is my code right now.
var fd = new FormData();
fd.append('attachment', file);
fd.append('uuid', uuid);
fd.append('userRoleId', userRole);
The code above works when appending a file that is taken from an <input type='file'> but doesn't work when just given the file path on the device.
Basically the FormData is showing like this right now:
------WebKitFormBoundaryasdf
Content-Disposition: form-data; name="attachment";
file://path/to/img
and I want it to look like this
------WebKitFormBoundaryasdf
Content-Disposition: form-data; name="attachment"; filename="jesus-quintana.jpg"
Content-Type: image/jpeg
I found many different ways to upload the image using cordova FileTransfer and by converting the image to a base64 and then uploading it. But I couldn't find any simple ways of just grabbing the file by using the path and posting it within a form. I'm not very familiar with the File Api so any help would be appreciated
After some fiddling around I manage to figure out a pretty simple solution.
First I added the cordova file plugin then I use the code below
var fd = new FormData();
window.resolveLocalFileSystemURL(attachment.img, function(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
var imgBlob = new Blob([ this.result ], { type: "image/jpeg" } );
fd.append('attachment', imgBlob);
fd.append('uuid', attachment.uuid);
fd.append('userRoleId', 12345);
console.log(fd);
//post form call here
};
reader.readAsArrayBuffer(file);
}, function(e){$scope.errorHandler(e)});
}, function(e){$scope.errorHandler(e)});
So I'm just creating a form and using FileReader to insert an ArrayBuffer to the Blob object and then append that to the form data. Hopefully this helps someone else looking for an easy way to do this.
You do need to send file content. With the HTML5 FileAPI you need to create a FileReader object.
Some time ago, I developed an application with cordova and I had to read some files, and I made a library called CoFS (first, by Cordova FileSystem, but it's working in some browsers).
It's on beta state, but I use it and works well. You can try to do some like this:
var errHandler = function (err) {
console.log("Error getting picture.", err);
};
var sendPicture = function (file) {
var fs = new CoFS();
fs.readFile(file, function (err, data) {
if (err) {
return errHandler(err);
}
var fd = new FormData();
fd.append('attachment', new Blob(data));
fd.append('uuid', uuid);
fd.append('userRoleId', userRole);
console.log("Data of file:" + data.toString('base64'));
// Send fd...
});
};
navigator.camera.getPicture(sendPicture, errHandler);
Sorry my poor english.
Your post was extremly helpful to fix my problem. I'm using Ionic 4 and trying to upload an image using standard http and file client. The key code for reference is here:
return this.file.readAsArrayBuffer(path, file).
then(blob => {
const imgBlob = new Blob([blob], { type: 'image/jpeg' } );
formData.append('image[file]', imgBlob);
return this.http.post(url, formData, headers).subscribe();
});
Hope it helps someone out there as it did for me.

Categories