2

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;

 };
colymore
  • 11,776
  • 13
  • 48
  • 90
  • Please show your client and server code – 23tux Jul 03 '14 at 10:21
  • 1
    See this other question -- http://stackoverflow.com/questions/21906340/upload-file-to-node-server-with-angular-file-upload – Matthew Bakaitis Jul 03 '14 at 11:52
  • lots of `sendByEmail`s with different arguments...doing different things? What is `BillService`? – PixnBits Jul 08 '14 at 19:10
  • BillService only send a file and a email as string to my NodeJS server, i receved it in sendByEmail(req...) and when i do a req.body.file i get the first source example, i put in a pdf but i cant open it, its corrupted – colymore Jul 08 '14 at 19:12

1 Answers1

1

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:

enter image description here

On the server:

enter image description here

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);
});
Community
  • 1
  • 1
Jorg
  • 7,219
  • 3
  • 44
  • 65
  • I have the PDF file in this object: var resultPdf = pdf.output();. Need i to do the the angular-js side code? – colymore Jul 10 '14 at 08:53
  • I have the same error whit this, i only set the server change, fs.writefFile..etc. I tried to open the pdf and give me an error. Im using express 3 – colymore Jul 10 '14 at 09:08
  • The PDF opens correctly with my setup. Can you confirm the data is sent in Base64? You can see by writing `req.body` to console in the post method in express. – Jorg Jul 10 '14 at 09:31
  • i cant find data:application/pdf;base64 in req.body.file ...Should i to convert it to base64 before send? – colymore Jul 10 '14 at 09:32
  • Base64 is what it should be in already after you retrieve it from `reader.result`. The string will start with `'data:application/pdf;base64,`. It's the most efficient way of sending and saving. it's what the email attachments generally use as well. I'm doing this in angular 1.2x by the way. – Jorg Jul 10 '14 at 09:34
  • How can i do it the reader..? I dont upload the file from my computer, its generated in time.. – colymore Jul 10 '14 at 09:35
  • oh, that was my assumption... where do you get the file from? – Jorg Jul 10 '14 at 10:11
  • I create the file with JSPDF library,but if i convert it to base64 with btoa function it works. Edit your anwser for both options( file input, and file created) and i will put your anwser as correct.Thanks – colymore Jul 10 '14 at 10:12