Giter Club home page Giter Club logo

meteor-pdfkit's Introduction

PDFKit

Create PDF with PDFKit Node.js package in your Meteor application, server-side only.

This package is based on PDFKit 0.4.3 and use Fiber, for best performances and non-blocking thread (but synchronous).

For the new pdfkit version (up to 0.7.1), server-side and client-side, please use the other package: pascoual:PDFKitx

Quick Start

  • meteor add pascoual:pdfkit
  • Example: create a PDF server-side
var doc = new PDFDocument({size: 'A4', margin: 50});
var imageBase64 = Meteor.users.findOne(this.userId).profile.picture;
var imageBuffer2 = new Buffer(imageBase64.replace('data:image/png;base64,','') || '', 'base64');
doc.image(imageBuffer2, 10, 10, {height: 75});
doc.fontSize(12);
doc.text('PDFKit is simple', 10, 30, {align: 'center', width: 200});
// Save it on myApp/public/pdf folder (or any place) with the Fibered sync methode:
doc.writeSync(process.env.PWD + '/public/pdf/PDFKitExample.pdf');
  • Example: a route that creates and serves a PDF (thanks @babak49)
 Router.route('/getPDF', function() {
 var doc = new PDFDocument({size: 'A4', margin: 50});
 doc.fontSize(12);
 doc.text('PDFKit is simple', 10, 30, {align: 'center', width: 200});
 this.response.writeHead(200, {
 'Content-type': 'application/pdf',
 'Content-Disposition': "attachment; filename=test.pdf"
 });
 this.response.end( doc.outputSync() );
 }, {where: 'server'});

Documentation

You can find information about the PDFKit node package here:

This package adds two Fibered methods (non-blocking thread, but synchronous):

  • writeSync(filename): saving the PDF in filename (can be a full path)
  • outputSync(): returning the PDF as binary String

Contributors

  • Pascal Richier @pascalrichier
  • Bogdan @babak49

Contributing

Contributors are very welcome. There are many things you can help with, including adding testing feature, creating examples for the examples folder... Some guidelines below:

  • Questions: It's okay to ask a question on Github Issues if you're having trouble since the volume is manageable. Just prefix your Github Issue with 'Question: ' so we can differentiate easily. Also, please make sure you've read through PDFKit documentation and tried a few things before asking. This way you can be very specific in your question. Also, please provide a cloneable Github repository if the issue is complex. For more complex questions sometimes it's hard to get all of the context required to solve a problem by just looking at text.

  • New Features & Bugs: You need to ask new features and bugs corrections to PDFKit creator on his GIT: https://github.com/devongovett/pdfkit/

  • Answer Questions!: If you can help another user please do!

TODO

  1. Add testing
  2. Check if PDFKit is blocking node or is fibered

License

MIT

meteor-pdfkit's People

Contributors

bogdan-bodnaruk avatar dandv avatar dimwell avatar pascoual avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

meteor-pdfkit's Issues

How to disable pdfkit client side

Hello,
As title said, I would like to disable meteor pdfkit for the client side, I don't know how to do that properly.

Do you have advise to do so?

Question: how to use outputSync

On atmosphere you mentioned using outputSync() to returning the PDF as binary String.
How is that done from within a server method? How do you catch this and display on the client side? Or perhaps I don't understand what you mean by that. Either way, an example of this would be helpful.

Question: get a return of writeSync()

Hi there!
Thanks for the nice package - works like a charm! :-)
Since you provide a sync function which write the file (writeSync) I wonder - why is there no return value of this function?
How can I know if creating and writing the pdf file was successful so I can move on in my code (in my case: send the pdf via e-mail)?

var write = doc.writeSync(process.env.PWD + '/public/pdf/' + orderid + '_order.pdf');
console.log('writefile return: ' + write);

Writing the file works just fine but write is always undefined.

Question: How to use?

Hey!

Thank you for providing this package. However, I can't really figure out how to use it. I'd like the pdf to be saved to the public/pdf/ folder. Could you provide a more in-depth explanation on how to do this?

Thanks,
Jan

Question: Using an image from project folder

Sorry for the newbie question, but I've been going around with this for a while.

I have an image in my public folder, which i want to use as a header in the pdf.
From the Quick Start example, i can see you use a image that is on the db. Is that necessary?

How do I use an image from my projects directory?

If i just use doc.image(imagePath), i get an error saying that that file/dir doesn't exist.

Thanks

Question:chinese display in pdfkit

Hello, I am using pdfkit to generate PDF in nodejs project, but the latter part of Chinese in pdf turn into white squares or missing with different font when read in a mobile phone browsing or in Adobe PDF.It is strange that using the PC web browser like Google Chrome is okay. What is more, when I comment some front code ,namely delete the front part of Chinese, white squares turn into Chinese.
Looking forward to your reply. Thank you!

`"use strict";
var PDFDocument = require('pdfkit');
var blobStream = require('blob-stream');
var fs = require('fs');

var pTitileX = cm2px(6.2);
var pTitileY = cm2px(1.8);
var leftRightSpace = cm2px(0.9);
var frame = {
w: 612 - leftRightSpace * 2,
h: 680,
vticalH1: cm2px(0.9),
vticalH2: cm2px(1.3)
};
var p00 = {
x: leftRightSpace,
y: cm2px(3.15)
};
var p08 = {
x: leftRightSpace,
y: 325
};
var p09 = {
x: leftRightSpace,
y: 340
};

var p018 = {
x: leftRightSpace,
y: 660
};

var p019 = {
x: leftRightSpace,
y: 700
};

var p020 = {
x: leftRightSpace,
y: p00.y + frame.h
};

var vvMark = {
a1: leftRightSpace + cm2px(5),
a2: leftRightSpace + cm2px(8),
a3: leftRightSpace + cm2px(10.25),
a4: leftRightSpace + cm2px(12.25),
a5: leftRightSpace + cm2px(14.25),
a6: leftRightSpace + cm2px(15.5),
a7: leftRightSpace + cm2px(16.2)
};

var vvTemp = 3;
var vvTextMark = {
a0: leftRightSpace + vvTemp,
a1: leftRightSpace + vvTemp + cm2px(5),
a2: leftRightSpace + vvTemp + cm2px(8),
a3: leftRightSpace + vvTemp + cm2px(10.25),
a4: leftRightSpace + vvTemp + cm2px(12.25),
a5: leftRightSpace + vvTemp + cm2px(14.25),
a6: leftRightSpace + vvTemp + cm2px(15.5),
a7: leftRightSpace + vvTemp + cm2px(16.2)
};

var ttMark = {
a0: leftRightSpace + vvTemp,
a1: leftRightSpace + cm2px(1.6),
a2: leftRightSpace + cm2px(3.8),
a3: leftRightSpace + cm2px(7.8),
a4: leftRightSpace + cm2px(10.2),
a5: leftRightSpace + cm2px(13.5),
a6: leftRightSpace + cm2px(15.2),
a7: leftRightSpace + cm2px(16.8),
a8: leftRightSpace + cm2px(17.9)
};

module.exports = {
// 获取
get: function (req, res, next) {
res.header('content-type', 'application/pdf');
res.write('');
var doc = new PDFDocument();
doc.page.width = 612;
doc.page.height = 792;

                var stream = doc.pipe(blobStream());

                //边框
                doc.lineWidth(1.5)
                          .lineJoin('bevel')
                          .undash()
                          .rect(p00.x, p00.y, frame.w, frame.h)
                          .stroke();

                //1-7线条
                for (var i = 0; i < 8; i++) {
                          doc
                                    .moveTo(p00.x, p00.y + i * frame.vticalH1)
                                    .lineTo(p00.x + frame.w, p00.y + i * frame.vticalH1)
                                    .lineWidth(1)
                                    .undash()
                                    .stroke();
                }

                //p08
                doc
                          .lineWidth(1)
                          .moveTo(p08.x, p08.y)
                          .lineTo(p08.x + frame.w, p08.y)
                          .stroke();

                //9-17线条
                for (var i = 0; i < 9; i++) {
                          if (i >= 1 && i <= 7) {
                                    doc
                                              .moveTo(p09.x, p09.y + i * frame.vticalH2)
                                              .lineTo(p09.x + frame.w, p09.y + i * frame.vticalH2)
                                              .lineWidth(0.5)
                                              .dash(1, 1)
                                              .stroke();
                          } else {
                                    doc
                                              .moveTo(p09.x, p09.y + i * frame.vticalH2)
                                              .lineTo(p09.x + frame.w, p09.y + i * frame.vticalH2)
                                              .lineWidth(1)
                                              .undash()
                                              .stroke();
                          }
                }

                doc
                          .moveTo(p018.x, p018.y)
                          .lineTo(p018.x + frame.w, p018.y)
                          .lineWidth(1)
                          .undash()
                          .stroke();

                //上部竖向线条
                doc
                          .moveTo(vvMark.a1, p1to7(3))
                          .lineTo(vvMark.a1, p1to7(7))
                          .moveTo(vvMark.a2, p1to7(0))
                          .lineTo(vvMark.a2, p1to7(3))
                          .moveTo(vvMark.a2, p1to7(4))
                          .lineTo(vvMark.a2, p1to7(6))
                          .moveTo(vvMark.a3, p1to7(1))
                          .lineTo(vvMark.a3, p1to7(2))
                          .moveTo(vvMark.a3, p1to7(3))
                          .lineTo(vvMark.a3, p1to7(4))
                          .moveTo(vvMark.a4, p1to7(0))
                          .lineTo(vvMark.a4, p1to7(1))
                          .moveTo(vvMark.a4, p1to7(2))
                          .lineTo(vvMark.a4, p1to7(3))
                          .moveTo(vvMark.a4, p1to7(4))
                          .lineTo(vvMark.a4, p1to7(6))
                          .moveTo(vvMark.a4, p1to7(4))
                          .lineTo(vvMark.a4, p1to7(6))
                          .moveTo(vvMark.a5, p1to7(1))
                          .lineTo(vvMark.a5, p1to7(2))
                          .moveTo(vvMark.a6, p1to7(2))
                          .lineTo(vvMark.a6, p1to7(6))
                          .moveTo(vvMark.a7, p1to7(0))
                          .lineTo(vvMark.a7, p1to7(1))
                          .lineWidth(1)
                          .undash()
                          .stroke();

                doc
                          .moveTo(p019.x, p019.y)
                          .lineTo(vvMark.a1, p019.y)
                          .lineTo(vvMark.a1, p018.y)
                          .lineWidth(1)
                          .undash()
                          .stroke();

                doc
                          .moveTo(vvMark.a4, p018.y)
                          .lineTo(vvMark.a4, p020.y)
                          .lineWidth(1)
                          .undash()
                          .stroke();

                doc
                          .fontSize(18)
                          .font(__dirname + '/simhei.ttf')
                          .text('中华人民共和国海关出口货物报关单', pTitileX, pTitileY)
                          .stroke();
                doc
                          .fontSize(9)
                          .font(__dirname + '/Deng.ttf')
                          .text('预录入编号:', 90, cm2px(2.7))
                          .text('海关编号:', 310, cm2px(2.7))
                          .text('收发货人', vvTextMark.a0, textP1to7(0))
                          .text('出口口岸', vvTextMark.a2, textP1to7(0))
                          .text('出口日期', vvTextMark.a4, textP1to7(0))
                          .text('申报日期', vvTextMark.a7, textP1to7(0))
                          .text('生产销售单位', vvTextMark.a0, textP1to7(1))
                          .text('运输方式', vvTextMark.a2, textP1to7(1))
                          .text('运输工具名称', vvTextMark.a3, textP1to7(1))
                          .text('提运单号', vvTextMark.a5, textP1to7(1))
                          .text('申报单位', vvTextMark.a0, textP1to7(2))
                          .text('监管方式', vvTextMark.a2, textP1to7(2))
                          .text('征免性质', vvTextMark.a4, textP1to7(2))
                          .text('备案号', vvTextMark.a6, textP1to7(2))
                          .text('贸易国(地区)', vvTextMark.a0, textP1to7(3))
                          .text('运抵国(地区)', vvTextMark.a1, textP1to7(3))
                          .text('指运港', vvTextMark.a3, textP1to7(3))
                          .text('境内货源地', vvTextMark.a6, textP1to7(3))
                          .text('许可证号', vvTextMark.a0, textP1to7(4))
                          .text('成交方式', vvTextMark.a1, textP1to7(4))
                          .text('运费', vvTextMark.a2, textP1to7(4))
                          .text('保费', vvTextMark.a4, textP1to7(4))
                          .text('杂费', vvTextMark.a6, textP1to7(4))
                          .text('合同协议号', vvTextMark.a0, textP1to7(5))
                          .text('件数', vvTextMark.a1, textP1to7(5))
                          .text('包装种类', vvTextMark.a2, textP1to7(5))
                          .text('毛重(千克)', vvTextMark.a4, textP1to7(5))
                          .text('净重(千克)', vvTextMark.a6, textP1to7(5))
                          .text('集装箱号', vvTextMark.a0, textP1to7(6))
                          .text('随附单证', vvTextMark.a1, textP1to7(6))
                          .text('标记唛码及备注', vvTextMark.a0, textP1to7(7))
                          .text('项号', vvTextMark.a0, p08.y + 3)
                          .text('商品编号', ttMark.a1, p08.y + 3)
                          .text('商品名称、规格型号', ttMark.a2, p08.y + 3)
                          .text('数量及单位', ttMark.a3, p08.y + 3)
                          .text('最终目的国(地区)', ttMark.a4, p08.y + 3)
                          .text('单价', ttMark.a5, p08.y + 3)
                          .text('总价', ttMark.a6, p08.y + 3)
                          .text('币制', ttMark.a7, p08.y + 3)
                          .text('征免', ttMark.a7, p08.y + 3)
                          .text('录入员', vvTextMark.a0, p018.y + 3)
                          .text('录入单位', 100, p018.y + 3)
                          .text('兹申明对以上内容承担如实申报、依法纳税之', vvTextMark.a1, p018.y + 3)
                          .text('海关批注及签章', vvTextMark.a4, p018.y + 3)
                          .text('法律责任', vvTextMark.a4, p018.y + 23)
                          .text('报关人员', vvTextMark.a0, p018.y + 43)
                          .text('申报单位(签章)', vvTextMark.a4, p018.y + 43)
                          .stroke();

                doc.end();
                doc.pipe(res);
      }

};

function p1to7(n) {
return p00.y + n * frame.vticalH1;
}
function p10to17(n) {
return p09.y + n * frame.vticalH2;
}

function textP1to7(n) {
return p00.y + n * frame.vticalH1 + 3;
}

function cm2px(value) {
return (value * 612 / 21.587);
}`

pdfkit ignores margin setting

creating a new document:
doc = new PDFDocument({size:'Letter', margin: 36});
Does not seem to actually set any margins. Text will start at the left edge of the page and run to the right edge of the page. All elements essentially have to be manually positioned. I've also tried setting the margins in separate addPage() calls, with similar lack of effect.
Not a huge problem, just a bit of a hassle and a documented feature that doesn't seem to be working in current meteor versions.

Error: EACCES, open

Any idea why I might be getting this error?

Exception while invoking method 'reportBatch' Error: EACCES, open '/app-storage/MeterBatchReport.pdf'
at Object.Future.wait (/mnt/data/2/node_modules/fibers/future.js:326:15)
at Object.writeFileFiber (packages/meteor/helpers.js:119:1)
at PDFDocument.writeSync (packages/pascoual:pdfkit/pdfkitWrapper.js:34:1)
at [object Object].Meteor.methods.reportBatch (app/server/server.js:33:13)
at maybeAuditArgumentChecks (packages/ddp/livedata_server.js:1599:1)
at packages/ddp/livedata_server.js:648:1
at [object Object]..extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
at packages/ddp/livedata_server.js:647:1
at [object Object].
.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
at [object Object]._.extend.protocol_handlers.method (packages/ddp/livedata_server.js:646:1)

below is my server-side code

reportBatch:function(dataUrl){
        var fs = Npm.require('fs');
        var path = Npm.require('path');

        var doc = new PDFDocument({size: 'A4', margin: 50});
        var buffer = new Buffer(dataUrl.split(",")[1], 'base64');

        doc.image(buffer, 10, 10);
        var dirPath = process.env.CLOUD_DIR;
        var filename = '/MeterBatchReport.pdf';
        var filepath = path.join(dirPath, filename);
        console.log(filepath);
        doc.writeSync(filepath);

    }

Why does it not work in production (Meteor-up)?

I write to file using:

doc.write(process.env.PWD + '/public/pdf/mypdf.pdf');

but it seems it tries to put my file in /opt/<appname>/public/pdf/, which doesn't exist. So I tried this instead (forcing it into the public folder):

doc.write(process.env.PWD + '/app/programs/client/app/pdf/mypdf.pdf');

This did neither work, the files gets written, but when I go to <my_server_path:port>/pdf/mypdf.pdf it does not show up. Do I have to manually set permissions or something?

ReferenceError: PDFDocument is not defined

I've tried to use a bit of the sample from the readme, but it errors out on the first bit, trying to use PDFDocument. Perhaps it's an issue with using it on 0.8.2 / 0.8.3?

Question: Create a pdf from a pdf template

I'm looking to generate a pdf from an existing pdf "template". For example, the pdf "template" would have the layout and text -- all that would be left to do is fill in "fields" with data.

I would like to populate these fields with the appropriate data from a mongo collection, and generate a new pdf from it. Is this possible with this package?

I reviewed http://pdfkit.org/ but found no examples of this approach.

Write is asynchronous

Methodes:

  • write
  • output

Are asynchronous and can't be used in Meteor Fibered code.

Meteor server restarts when call of writeSync()

In Meteor.methods on the server, I have the following method:

createPdf: function() {
    var doc = new PDFDocument({size: 'A4', margin: 50});
    doc.fontSize(12);
    doc.text('Simple document', 10, 30, {align: 'center', width: 200});
    doc.writeSync(process.env.PWD + '/public/doc.pdf');
}

When I call this method by Meteor.call(), the server restarts. The document is being created though. Any suggestions?

Question: How to use with angular-meteor / angular-ui-router

Hello,
I'm trying to implement something similar to the iron-router example, where a user could click a button and a PDF file would be generated and served to the client for download (not stored on the server). Any thoughts on how I might go about this using urigo:angular-ui-router instead of iron?
Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.