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("[email protected]", 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;

 };
4
  • Please show your client and server code Commented Jul 3, 2014 at 10:21
  • 1
    See this other question -- stackoverflow.com/questions/21906340/… Commented Jul 3, 2014 at 11:52
  • lots of sendByEmails with different arguments...doing different things? What is BillService? Commented Jul 8, 2014 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 Commented Jul 8, 2014 at 19:12

1 Answer 1

1
+50

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);
});
Sign up to request clarification or add additional context in comments.

8 Comments

I have the PDF file in this object: var resultPdf = pdf.output();. Need i to do the the angular-js side code?
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
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.
i cant find data:application/pdf;base64 in req.body.file ...Should i to convert it to base64 before send?
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.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.