Giter VIP home page Giter VIP logo

one-file-pdf's Introduction

one-file-pdf - A minimalist PDF generator in <2K lines and 1 file

Go Report Card Build Status Test Coverage Gitter chat godoc License: MIT

The main idea behind this project was:
"How small can I make a PDF generator for it to still be useful for 80% of common PDF generation needs?"

The result is a single .go file with less than 1999 lines of code, about 400 of which are color and glyph-size constants, and ~350 are comments.

  • It's easier to learn about the internals of the PDF format with a small, concise library.
  • The current version of the file is indicated in the header (the timestamp).

Features:

  • The essentials for generating PDF documents, sufficient for common business reports.
  • Use all built-in PDF fonts: Courier, Helvetica, Symbol, Times, ZapfDingbats, and their variants
  • Specify colo(u)rs by name (144 web colors), HTML codes (#RRGGBB) or RGB value
  • Set columns for text (like tab stops on the page)
  • Built-in grid option to help measurement and positioning
  • Metadata properties: author, creator, keywords, subject and title
  • Set the measurement units you want: mm, cm, inches, twips or points
  • Draw lines with different thickness
  • Filled or outline rectangles, circles and ellipses
  • JPEG, GIF and transparent PNG images (filled with specified background color)
  • Stream compression can be turned on or off (PDF files normally compress streams to reduce file size, but turning it off helps in debugging or learning about PDF commands)

Not Yet Supported:

  • Unicode (requires font embedding)
  • Font embedding
  • PDF encryption
  • Paths, curves and complex graphics

Installation:

    go get github.com/balacode/one-file-pdf

Naming Convention:

All types in are prefixed with PDF for public, and 'pdf' for private types. The only type you need to use is PDF, while PDFColorNames are left public for reference.

Hello World:

package main 

import (
	"fmt"
	"github.com/balacode/one-file-pdf"
)

func main() {
    fmt.Println(`Generating a "Hello World" PDF...`)

    // create a new PDF using 'A4' page size
    var pdf = pdf.NewPDF("A4")

    // set the measurement units to centimeters
    pdf.SetUnits("cm")

    // draw a grid to help us align stuff (just a guide, not necessary)
    pdf.DrawUnitGrid()

    // draw the word 'HELLO' in orange, using 100pt bold Helvetica font
    // - text is placed on top of, not below the Y-coordinate
    // - you can use method chaining
    pdf.SetFont("Helvetica-Bold", 100).
        SetXY(5, 5).
        SetColor("Orange").
        DrawText("HELLO")

    // draw the word 'WORLD' in blue-violet, using 100pt Helvetica font
    // note that here we use the colo(u)r hex code instead
    // of its name, using the CSS/HTML format: #RRGGBB
    pdf.SetXY(5, 9).
        SetColor("#8A2BE2").
        SetFont("Helvetica", 100).
        DrawText("WORLD!")

    // draw a flower icon using 300pt Zapf-Dingbats font
    pdf.SetX(7).SetY(17).
        SetColorRGB(255, 0, 0).
        SetFont("ZapfDingbats", 300).
        DrawText("a")

    // save the file:
    // if the file exists, it will be overwritten
    // if the file is in use, prints an error message
    pdf.SaveFile("hello.pdf")
} //                                                                        main

Samples:

Click on a sample to see the PDF in more detail.

"Hello World!" sample image

"Synergy Ipsum" sample image

Changelog:

These are the most recent changes in the functionality of the package, not including internal changes which are best seen in the commits history.

2018-04-14

  • Changed CurrentPage from read-only to read/write property: added SetCurrentPage()
  • Created PageCount() read-only property
  • Created dingbats() demo to generate zapf_dingbats_table.pdf. You can use this table to look up the hex code for each icon.
  • Changed text encoding from /WinAnsiEncoding to /StandardEncoding

See changelog.md for changes made earlier.

Roadmap:

  • Achieve 100% test coverage
  • Create a unit test for every method
  • Unicode support
  • Partial font embedding

one-file-pdf's People

Contributors

balacode avatar bholdsworthamplify avatar brianholdsworth avatar marcosinger 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  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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

one-file-pdf's Issues

Streaming mode

Hello, first of all, I like this library, minimal yet powerful.

I have one question; does the API support streaming the pdf to disk, that way one could write lots of data to the PDF without being held in memory all at once?

NextLine() calc seems wrong

I tried to use nextline() and the x was zeroed but the Y was set o 2019.987654.
Something is not correct in the compute or the various devfaults.

PNG embedding is slow

Noticeable time (about 1 second) is spent when generating png_images.pdf

  • Is the library regenerating every PNG image, even if it is repeated?
  • If decoding and re-encoding the image data in a PDF stream is a slow operation, then goroutines could be used to speed up the process.

How to support Unicode in the PDF format?

Unicode support is essential in modern software, so we are going to implement some kind of Unicode support in this PDF writer. If you know or can link to any information about font embedding (to enable Unicode) or just referencing external fonts installed on the system in order to use Unicode, please let me know. Thanks for your attention.

Return error(s) where possible please

How to know that SaveFile failed except by reading log?
Please return errors instead of logging them.

Application code should log, libraries should not log but return errors.

Other than that good library looking forward using it. Thanks.

png_images.pdf (demo) is larger than estimated

The generated png_images.pdf is about 6MB in size,
but based on my estimates it should be under 3MB:

dice.png is 420 x 315 pixels = 132,300 pixels
132,300 pixels x 3 colors = 396,900 bytes for RGB data
396,900 x 5 background varieties = 1,984,500 bytes

gophers.png is 600 x 476 pixels = 285,600 pixels
285,600 x 3 colors = 856,800 bytes for RGB data

Additional data for PDF commands, let's say 200K

The file size should be about 3MB,
but the generated demo is 6MB

** What to consider: **

  • Is the library reusing all repeated images?
  • Can the image byte stream be compressed to save space?

PDF Metadata not properly encoded

The metadata fields like Title, Subject, Author, etc. are not shown in the rendered PDF because the /Type/Info object isn't properly delimited by the code.

To fix this, add call to pdf.writeObj near line 1081, like so:

screen shot 2018-03-05 at 10 43 19 am

SaveFile method creates unreadable file

In SaveFile, ioutil.WriteFile is used to save the file without any file attributes. Therefore, the file cannot be read until one performs a chmod to set reasonable attributes.

var err = ioutil.WriteFile(filename, pdf.Bytes(), 0)

should be

var err = ioutil.WriteFile(filename, pdf.Bytes(), 0644)

No support for simple color (RGB) PNG images

I have been experimenting with using color PNG images with DrawImage() method, and so far found this to work with just a two line change. Is there much more than this needed in order to officially support color images instead of grayscale?

screen shot 2018-03-11 at 10 34 59 pm
screen shot 2018-03-11 at 10 35 20 pm

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.