317

I’m trying to convert XML data into PDF files from a web page and I was hoping I could do this entirely within JavaScript. I need to be able to draw text, images and simple shapes. I would love to be able to do this entirely in the browser.

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
amoeba
  • 4,015
  • 3
  • 21
  • 14

7 Answers7

537

I've just written a library called jsPDF which generates PDFs using Javascript alone. It's still very young, and I'll be adding features and bug fixes soon. Also got a few ideas for workarounds in browsers that do not support Data URIs. It's licensed under a liberal MIT license.

I came across this question before I started writing it and thought I'd come back and let you know :)

Generate PDFs in Javascript

Example create a "Hello World" PDF file.

// Default export is a4 paper, portrait, using milimeters for units
var doc = new jsPDF()

doc.text('Hello world!', 10, 10)
doc.save('a4.pdf')
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.debug.js"></script>
Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
James Hall
  • 7,507
  • 2
  • 22
  • 15
  • 16
    Did I partially inspire jsPDF? I learned about jsPDF the day you announced it. Looking great so far. I ended up going with Prawn as it's easily the best PDF generation library out there for my requirements. I would still love to do all of my work in-browser as I'm not positive I'll get Ruby on the system I'm deploying to. I'm watching jsPDF very closely. I would love to help out but my time is very limited. That might change in the future. – amoeba May 04 '09 at 19:40
  • 11
    You did inspire it somewhat :), I was looking around on the internet to see if it already existed and saw that some people would find it useful. Let me know if you'd like to help out. I'm @MrRio on twitter. – James Hall May 07 '09 at 09:22
  • does not have image embedding as far as I know. – Timo Huovinen Jan 17 '12 at 15:49
  • This seems to work only in Chrome. FF8 and IE9 did not run this code – AntonioCS Feb 02 '12 at 12:57
  • 25
    It's still very much alive. 0.9.0rc2 Released today. – James Hall Apr 07 '13 at 22:00
  • 112
    @JamesHall, I'd like to thank you for all the work it must be taking to write this, and for MIT licensing it to make the world a better place when you could have commercialized it for your own gain. – Charles Burns Sep 26 '13 at 14:58
  • 2
    A huge drawback: it does not support UTF-8. So, russian, czech or chinese texts wont work! – João Pimentel Ferreira Sep 24 '14 at 15:25
  • another big drawback i guess is no support for CSS, fonts etc. I mean for a dynamically created div how would i know which line will have which font? so I have used CSS. but it seems this lib can not read that. – rajeev Dec 03 '14 at 16:59
  • When will it be possible to save a div with css as a pdf? For a project at work I need to include piecharts and such. Any possibility with this library? – Nicholas Mar 05 '15 at 09:31
  • 22
    Can downvoters offer us their "better" ideas or solutions? This is an excellent effort. – Onur Yıldırım Apr 28 '15 at 21:20
  • @JamesHall but what about css issues..this plugin doesn't support even inline css – Gaurav Aggarwal May 06 '16 at 07:02
  • 2
    Absolutely abysmal documentation all around. On top of this, the public api is not visible anywhere. – Gima Sep 07 '16 at 18:22
  • chrome crashes when clubbed with html2canvas for huge html file ! – Rizwan Patel Nov 18 '16 at 11:04
  • 1
    jsPDF serious need a better documentation – TheCrazyProfessor Nov 05 '17 at 22:45
  • 1
    @JamesHall wondering if this partially implements the PDF spec, or how much of it you covered. – Lance Jul 23 '18 at 04:14
  • tried it, it walls with call stack exceeded for a 150kb txt file – Konstantin Vahrushev Jul 05 '19 at 10:36
  • We've been working with JsPDF and autotables which is nice but unfortunately it really doesn't work very well with UTF 8 characters, we were able to add custom fonts but it's very unstable, sometimes work sometimes doesn't for reasons that are not possible to figure out clearly – Tibo Oct 24 '20 at 08:16
  • How do you resize text or do h1s or add css James? – Promaster Oct 24 '20 at 18:27
167

Another javascript library worth mentioning is pdfmake.

The browser support does not appear to be as strong as jsPDF, nor does there seem to be an option for shapes, but the options for formatting text are more advanced then the options currently available in jsPDF.

mg1075
  • 17,985
  • 8
  • 59
  • 100
  • 11
    This answer should be upvoted a lot more, pdfmake is so much more robust than jspdf. However just a side note, it is wrapper around PDFKit library. – vittore Apr 19 '15 at 19:27
  • 4
    another side note, jspdf doesn't have utf-8 support and pdfmake has utf-8 support only for default fonts. – Leo Apr 05 '16 at 07:21
  • "pdfmake.min.js - 0.1.22 - 9 hours ago" It is not dead, updated this day. – zenbeni Dec 23 '16 at 15:43
  • 1
    From comparing the two playgrounds, to me it seems that jsPDF is more targeted at "graphic" PDF creation, whereas pdfmake is targeted more at generating well-formatted "plain" documents, it seems to have a lot more options for generic text formatting. – cslotty Dec 17 '17 at 10:31
  • 1
    Is this IE friendly? – Wildhammer Jun 27 '19 at 18:33
75

I maintain PDFKit, which also powers pdfmake (already mentioned here). It works in both Node and the browser, and supports a bunch of stuff that other libraries do not:

  • Embedding subsetted fonts, with support for unicode.
  • Lots of advanced text layout stuff (columns, page breaking, full unicode line breaking, basic rich text, etc.).
  • Working on even more font stuff for advanced typography (OpenType/AAT ligatures, contextual substitution, etc.). Coming soon: see the fontkit branch if you're interested.
  • More graphics stuff: gradients, etc.
  • Built with modern tools like browserify and streams. Usable both in the browser and node.

Check out http://pdfkit.org/ for a full tutorial to see for yourself what PDFKit can do. And for an example of what kinds of documents can be produced, check out the docs as a PDF generated from some Markdown files using PDFKit itself: http://pdfkit.org/docs/guide.pdf.

You can also try it out interactively in the browser here: http://pdfkit.org/demo/browser.html.

devongovett
  • 4,850
  • 5
  • 34
  • 35
  • 1
    Isn't this a server side library? I think the discussion is on the client side js library. – Ash Catchem Mar 16 '15 at 15:53
  • 12
    PDFKit works in both Node and the browser as mentioned in the answer. See the link to a browser demo. – devongovett Mar 17 '15 at 10:06
  • Does this compress images? I am working on a web app that functions similar to camscanner and I am looking for PDF creation through javascript to leverage the compression and multi page format. – Trevor Jul 04 '17 at 14:47
  • @devongovett can you look at my [question](https://stackoverflow.com/questions/55190357/pdfkit-browser-uncaught-referenceerror-fs-is-not-defined-when-using-custom) about your library? – ninbit Mar 15 '19 at 20:41
  • I've been using PDFKit recently and although it has a few glitches it does work well and is very solid. I would recommend it. – Paul Pritchard Jul 06 '21 at 09:09
14

Another interesting project is texlive.js.

It allows you to compile (La)TeX to PDF in the browser.

Kpym
  • 3,743
  • 1
  • 21
  • 18
7

For react fans there is another great resource for PDF generation: React-PDF

It is great for creating PDF files in React and even let the user download them from the client side itself with no server required!

this is a small example snippet of React-PDF to create a 2 section PDF file

import React from 'react';
import { Page, Text, View, Document, StyleSheet } from '@react-pdf/renderer';

// Create styles
const styles = StyleSheet.create({
  page: {
    flexDirection: 'row',
    backgroundColor: '#E4E4E4'
  },
  section: {
    margin: 10,
    padding: 10,
    flexGrow: 1
  }
});

// Create Document Component
const MyDocument = () => (
  <Document>
    <Page size="A4" style={styles.page}>
      <View style={styles.section}>
        <Text>Section #1</Text>
      </View>
      <View style={styles.section}>
        <Text>Section #2</Text>
      </View>
    </Page>
  </Document>
);

This will produce a PDF document with a single page. Inside, two different blocks, each of them rendering a different text. These are not the only valid primitives you can use. you can refer to the Components or Examples sections for more information.

Dev Sebastian
  • 587
  • 6
  • 11
3

It is worth mentioning PDF-LIB which is an awesome library:

  • Supports pure JavaScript.

  • Can edit existing PDF templates even with pure JavaScript. (Most impotently. Many JavaScript libraries can't do it)

  • It is generating a PDF with select-able/copy-able/highlight-able text not an image file inside an PDF like many other libraries generate.

  • More easy to use. (I love it) enter image description here

  • If you are interested in using it with pure JavaScript this may help.

  • If you are interested to do the same with the most popular JavaScript library as of now JSPDF this may help. (Simply JSPdf can't do most time saving thing we want, editing an existing template.)

See how pretty the code is

    <script type="text/javascript">
        async function downloadPdf() {

            const url = './print-templates/pquot-template.pdf';
            const existingPdfBytes = await fetch(url).then(res => res.arrayBuffer());

            // Getting the document
            const pdfDoc = await PDFLib.PDFDocument.load(existingPdfBytes);

            // Getting the first page
            const pages = pdfDoc.getPages();
            const firstPage = pages[0];

            // Customer name
            firstPage.drawText('Customer name is here with more text (GAR004) quick brown customerm jumps over lazy dog.', {
                x: 10.5*9,
                y: 76.6*9,
                size: 10,
                maxWidth: 28*9, // Wrap text with one line. WOW :O
                lineHeight: 1.5*9
            });

            // Currency short code
            firstPage.drawText('LKR', {
                x: 10.5*9,
                y: 73.5*9,
                size: 10
            });

            var itemName = 'Here is the item name with some really really long text and quick brown fox jumps over lazy dog. long text and quick brown fox jumps over lazy dog:)';
            // Item name
            firstPage.drawText(itemName, {
                x: 5*9,
                y: 67*9,
                size: 10,
                maxWidth: 31*9,
                lineHeight: 2*9
            });

            const pdfDataUri = await pdfDoc.saveAsBase64({ dataUri: true });
            document.getElementById('pdf').src = pdfDataUri;
        }

    </script>
Lakshitha Kanchana
  • 844
  • 2
  • 12
  • 32
-3

UPDATE: Free service no longer available. But there is a reasonably priced service you can use if you need something in a crunch and it's should be reliable.

https://pdfmyurl.com/plans

You can use this free service by adding a link which creates pdf from any url (e.g. http://www.phys.org):

http://freehtmltopdf.com/?convert=http%3A%2F%2Fwww.phys.org&size=US_Letter&orientation=portrait&framesize=800&language=en

boateng
  • 910
  • 11
  • 21
  • 2
    Update: When I went to check this http://freehtmltopdf.com service it said it was no longer available. Sounds like it was amazing though! – Mark Duiker Aug 10 '16 at 19:36
  • checked now - works. and it is amazing, i use a service where i pay for each pdf, and need to code, this is such a problem solver. – Sergey Sob Dec 26 '16 at 17:16