GithubHelp home page GithubHelp logo

ishaq / simplepdf Goto Github PK

View Code? Open in Web Editor NEW
54.0 8.0 17.0 142 KB

A Swift class to easily generate simple PDF documents with page numbers and Table of Contents.

License: MIT License

Swift 97.86% Ruby 2.14%
pdf-page pdf-document swift page-count

simplepdf's Introduction

SimplePDF

This class is no longer maintained by me. If you want to take over, send me an email!

SimplePDF is a Swift class that lets you create simple PDF documents with page numbers and table of contents. The code is a rough implementation of Builder design pattern. See the demo project for usage example.

Usage

To run the example project, clone the repo, and run pod install from the Example directory first. Or run pod try SimplePDFSwift.

⚠️ Important: Pod for this library is called SimplePDFSwift, Please note that pod named SimplePDF is a different library (It is available here if you'd like to try it). ⚠️

Requirements

SimplePDF is written in Swift 3.0 as of version 0.2.1. Therefore you need Xcode 8.0 for development. You can target iOS 8.0 and later.

To use SimplePDF on previous versions of Swift, you can use a version earlier than 0.2.1.

Installation

SimplePDF is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "SimplePDFSwift"

Features

Although SimplePDF can only generate simple PDF documents, It can be used in a variety of use cases. It allows you to add:

  • Headings (H1 - H6) and Body Text. Their formatting can be customized by passing a subclass of DefaultTextFormatter to SimplePDF init method
  • Images (with captions)
  • Add text to multiple columns, it can also be used to create borderless tables
  • Headers/Footers (with page number and pages-count)
  • UIView instances (You can design a UIView in a nib or in a storyboard and add it as a page to the PDF. This can be useful to add, for example, a cover page with company logo, etc.)

In addition to predefined headings and body text formats, you can also add any NSAttributedString to the pdf, however it will not be included in Table of Contents. Table of Contents only takes into account the content added through addH1 ... addH6 functions.

Getting Started

After installation from CocoaPods, import the module (import SimplePDFSwift). A typical usage would look like:

import SimplePDFSwift

// Initialize
let pdf = SimplePDF(pdfTitle: "Simple PDF Demo", authorName: "Muhammad Ishaq")

// add some content
pdf.addH1("Level 2 Heading")
pdf.addBodyText("Some body text, probably a long string with multiple paras")
pdf.addH2("Level 2 Heading")
pdf.addBodyText("Lorem ipsum dolor sit amet...")

// add an image
let imagePath = NSBundle.mainBundle().pathForResource("Demo", ofType: "png")!
let imageCaption = "fig 1: Lorem ipsum dolor sit amet"
pdf.addImages([imagePath], imageCaptions: [imageCaption], imagesPerRow: 1)

// Configure headers/footers (discussed below)
// ...

// Write PDF
// Note that the tmpPDFPath is path to a temporary file, it needs to be saved somewhere
let tmpPDFPath = pdf.writePDFWithTableOfContents()

If you don't want a table of contents to be generated, instead of writePDFWithTableOfContents, you can call writePDFWithoutTableOfContents().

Adding Headers/Footers

There are two types of Headers/Footers.

  1. Text This is added using HeaderFooterText instance, any new line characters result in multiline header (or footer). This can, for example, be the name of the author and document creation date, or it can be the page number e.g. "Page 1 of 12" or any other text.

  2. Image: This is added using HeaderFooterImage instance and can only be a single image (e.g. an icon or logo).

Alignment: Header/Footer can have Left, Center or Right alignment, It will be added to the corresponding location on top/bottom of the page.

pPage Number & Pages Count: In a text header/footer, occurrences of SimplePDF.pageNumberPlaceholder are replaced with the current page number and occurrences of SimplePDF.pagesCountPlaceholder are replaced with pages-count.

The pageRange attribute controls which pages the header/footer appears on. pageRange is an NSRange instance, pageRange.location specifies zero based page index where the header/footer would first appear. pageRange.length specifies how many pages it would appear on (starting at pageRange.location).

Here's how a multiline header (or footer) could be added (in this case it is a header on the left and first appears on the second page):

// Variables to format the header string
let regularFont = UIFont.systemFontOfSize(8)
let boldFont = UIFont.boldSystemFontOfSize(8)
let leftAlignment = NSMutableParagraphStyle()
leftAlignment.alignment = NSTextAlignment.Left
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle
dateFormatter.timeStyle = NSDateFormatterStyle.MediumStyle
let dateString = dateFormatter.stringFromDate(NSDate())

// Create the attributed string for header
let leftHeaderString = "Author: Muhammad Ishaq\nDate/Time: \(dateString)"
let leftHeaderAttrString = NSMutableAttributedString(string: leftHeaderString)
leftHeaderAttrString.addAttribute(NSParagraphStyleAttributeName, value: leftAlignment, range: NSMakeRange(0, leftHeaderAttrString.length))
leftHeaderAttrString.addAttribute(NSFontAttributeName, value: regularFont, range: NSMakeRange(0, leftHeaderAttrString.length))
leftHeaderAttrString.addAttribute(NSFontAttributeName, value: boldFont, range: leftHeaderAttrString.mutableString.rangeOfString("Author:"))
leftHeaderAttrString.addAttribute(NSFontAttributeName, value: boldFont, range: leftHeaderAttrString.mutableString.rangeOfString("Date/Time:"))

// Create the header
// location of pageRange is 1, so it skips page 0 i.e. the first page and appears on second page
let header = SimplePDF.HeaderFooterText(type: .Header, pageRange: NSMakeRange(1, Int.max), attributedString: leftHeaderAttrString)
pdf.headerFooterTexts.append(header)

Here's how a logo could be added

// add a logo to the header, on the right
let logoPath = NSBundle.mainBundle().pathForResource("Demo", ofType: "png")
// location of pageRange is 1, so it skips page 0 i.e. the first page
// NOTE: we can specify either the image (UIImage instance) or its path
let rightLogo = SimplePDF.HeaderFooterImage(type: .Header, pageRange: NSMakeRange(1, Int.max),
    imagePath: logoPath!, image:nil, imageHeight: 35, alignment: .Right)
pdf.headerFooterImages.append(rightLogo)

And here's how page number with pages-count could be added

// add page numbers to the footer (center aligned)
let centerAlignment = NSMutableParagraphStyle()
centerAlignment.alignment = .Center
let footerString = NSMutableAttributedString(string: "\(SimplePDF.pageNumberPlaceholder) of \(SimplePDF.pagesCountPlaceholder)")
footerString.addAttribute(NSParagraphStyleAttributeName, value: centerAlignment, range: NSMakeRange(0, footerString.length))
// location of pageRange is 1, so it skips page 0 i.e. the first page
let footer = SimplePDF.HeaderFooterText(type: .Footer, pageRange: NSMakeRange(1, Int.max), attributedString: footerString)
pdf.headerFooterTexts.append(footer)

Adding a View

You can call addView(view) to render UIView instances to a PDF page. The passed view will be rendered new PDF page. This is mostly useful to design cover pages. A view is always added to its own page. It starts a new page if required, and any content added after it appears on the next page.

Here's how you can design a cover page with a UIView (or a subclass)

  1. Create a nib with the same dimensions as PDF page (e.g. A4 page is 595x842, you can lookup other dimensions in PageSize enum).
  2. Optional: If you want the labels to appear as text (instead of bitmaps) in the PDF, all the labels in the view should have their class set to SimplePDFLabel (or a subclass of it).
  3. Load the view from the nib and add it to pdf
let coverPage = NSBundle.mainBundle().loadNibNamed("PDFCoverPage", owner: self, options: nil).first as PDFCoverPage
pdf.addView(coverPage)

Note: Please note that if you use the above method to render a view to PDF, AutoLayout will not be run on it, If your view doesn't rely on AutoLayout, you don't need to worry about anything. However, if your view uses AutoLayout to correctly position elements, you have to add it to the active view hierarchy. You can add to the view hierarchy off-screen, then call pdf.addView(view) to render it to PDF. But now the view would render as bitmap. This means any labels will not be selectable as text and they would lose quality (being bitmaps) if you zoom in.

Customizing Heading and Body Text Formatting

To customize the formatting used in addH1 ... addH6 and addBodyText functions, you need to:

  1. Subclass DefaultTextFormatter and override appropriate methods
  2. Pass instance of your custom subclass to SimplePDF's init.

SimplePDF will now use your subclass instead of DefaultTextFormatter to format headings and body text.

Other Tasks

  • You can add attributed strings with addAttributedString(attrString). Note, however, that these strings will not appear in table of contents (no matter how big the rendered text is).
  • You can add text to multiple columns with addAttributedStringsToColumns(columnWidths: [CGFloat], strings: [NSAttributedString]). This can also be used to create borderless tables. Passing empty string keeps corresponding column empty.
  • addImages(imagePaths:[String], imageCaptions: [String], imagesPerRow:Int = 3) adds images to pdf. It resizes the images uniformly to fit imagesPerRow images in available page width. Passing nil for image (and empty string for caption) keeps corresponding column empty.
  • addImagesRow(imagePaths: [String], imageCaptions: [NSAttributedString], columnWidths: [CGFloat]) adds a single row of images using column widths specified. Passing nil for image (and empty string for caption) keeps corresponding column empty.

Authors

Muhammad Ishaq ([email protected]), Martin Stemmle ([email protected])

License

SimplePDF is available under the MIT license. See the LICENSE file for more info.

simplepdf's People

Contributors

ishaq avatar kf99916 avatar martnst 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

simplepdf's Issues

Table Of Content Title

Hello, for generating PDF your framework seems one of the most complete, so congrats.
However, I encounter an issue regarding the table of content.

It seems to be that the title of it is hard coded so it cannot be translated.

Is there a way to translate it, customize it or at least removing it ?

merge osx branch to master

this would effectively add support for osx platform too.

also update authors section to include contributors' names.

Add column with image and text side by side

First of all, many thanks for making this library which really help people to solve their problem with almost all the scenario/requirement.

Is there a way to add column with image and text ?

for e.g.

screen shot 2017-11-22 at 8 19 17 pm

I know, we can add text to multiple columns with addAttributedStringsToColumns(columnWidths: [CGFloat], strings: [NSAttributedString]) but if this method can provide an additonal parameter for image would really help me.

any advice and suggestions will be greatly appreciated.

Modify existing pdf file?

Thank you for creating such an awesome library!

Let's say I have a pdf file, it's very long but there is not table of contents.

Is it possible to use SimplePDF to modify the pdf file?

How add tableview content?

I want to add tableview content which has 7 column and 300 rows....?
i had create tableview and then i had try to add in addview method

like
pdf.addView(tableView)
but it only show data how much display in screen....that are not create pdf with full data

Get image from document directory

Hello @ishaq,

Thank you for great OpenSource.

Right now we can choose image from Main bundle as below:

let imagePath = NSBundle.mainBundle().pathForResource("Demo", ofType: "png")!

Is it possible we get image from document directory? Or there is something I am missing?

Draw a line

Can you make drawLine method as public so we can draw a separator between two horizontal texts

for e.g.

First Line

Second Line

Release 0.1.2

need to update read me, fix typos and garammer mistakes

How to create tables

Hi,

Well over all your library is awesome.
Is there any way to create tables with borders. If yes please point me to any example.

Also how to set specific attributes to the table or custom html.

Thanks

add date and signature above the footer

Hello ishaq we have implemented Simple pdf in our project which needed to be little modified. We need to add date and signature just above the footer i have tried all possible ways but they failed can you please help ?

Header footer

Not able to add header footer in first page.
Pls help me how to add Header and footer on first page.

Thanks in advance

Error in installing Podfile

Hi Muhammed
I would like to test your SimplePDF.

I downloaded the ZIP file of ur project but when I install the Podfile I get this:

[!] Invalid Podfile file: [!] Unsupported options {:exclusive=>true} for target SimplePDF_Example..

from /Users/Desktop/SimplePDF-master/Example/Podfile:4

-------------------------------------------

target 'SimplePDF_Example', :exclusive => true do

pod 'SimplePDFSwift', :path => '../'

note:
The SImplePDF-Master directory has no either SimplePDF_Example nor SimplePDF_Tests files.

Am I missing something here?

Also, when I add import SimplePDFSwift to my xcodeproject it says "no such Module "SimplePDFSwift"
eventhough the I successfully installed the podfile.
i used this in the podfile:

  use_frameworks!
  target "mytestfile" do
            pod 'SimplePDFSwift'

end

Thanks for your help!

Cannot find preview item for proxy

Thank you for this great code, really appreciate your wonderful job.
There is a warning when i run the application:
SimplePDFDemo[1121:52299] Cannot find preview item for proxy: <QLPreviewItemProxy: 0x7fb9fb100a10> - SimplePDF 1.pdf (0)

any advise?

Remove number from Pdf title.

Hello! Thanks for the nice plugin. I am facing an issue is that everytime i reopen simulator it increment a number in pdftitle. Check the image for reference. It was added 69 in PDF title at the moment. I want to remove that number from the navigation title.

pdf

Update to swift 3

Dear Ishaq,
your code is just awesome, great, just no words enough for it.
when i update to swift 3, there is lot of error on it.

did you update the files to swift 3?

god bless you.
Regards

Crash if CFBundleName not set

In case the CFBundleName is not set it crashes do to forced casting into String over here.
I recommend checking for CFBundleDisplayName alternatively.

fuction add view can't be removed

hi , i can't remove th view of the xib that i added
when i use the function add view my first interface will disappear ,it will be replaced with this view and i can't return to it

pdf.addView(view) Position

Salam!
Thanks for your great work! I found your code very useful.

I am trying to add Signature (small rectangle UIView) at the bottom left of the PDF. Right now every time I use pdf.addView(Signature), it goes at the very top left of the page?

My question is how could I make it to the bottom?

I know you mentioned that the UIView must be added to an active view hierarchy- off-screen- could you please provide more information on how to that? I tried to add views and sub views with different position values programmatically, but I always get the UIview at the top left.

please forgive my ignorance if my question is simple. I am still new and learning about swift development!

BarakaAlloho feek!

Regards,

Improve formatting of Table of Contents

Right now all text in table of contents is same font size/weight, it should follow the elements represented i.e. table of content entry of Heading 1 should be bigger/bolder than the entry for Heading 2

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.