Skip to content

Instantly share code, notes, and snippets.

@nyg
Last active April 2, 2024 11:09
Show Gist options
  • Save nyg/b8cd742250826cb1471f to your computer and use it in GitHub Desktop.
Save nyg/b8cd742250826cb1471f to your computer and use it in GitHub Desktop.
iOS, Swift: Create a PDF file from an HTML string.
// Thanks to http://www.labs.saachitech.com/2012/10/23/pdf-generation-using-uiprintpagerenderer
// Note: including images in the HTML won't work, see here:
// https://github.com/nyg/HTMLWithImagesToPDF
import UIKit
// 1. Create a print formatter
let html = "<b>Hello <i>World!</i></b>"
let fmt = UIMarkupTextPrintFormatter(markupText: html)
// 2. Assign print formatter to UIPrintPageRenderer
let render = UIPrintPageRenderer()
render.addPrintFormatter(fmt, startingAtPageAt: 0)
// 3. Assign paperRect and printableRect
let page = CGRect(x: 0, y: 0, width: 595.2, height: 841.8) // A4, 72 dpi
render.setValue(page, forKey: "paperRect")
render.setValue(page, forKey: "printableRect")
// 4. Create PDF context and draw
let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, .zero, nil)
for i in 0..<render.numberOfPages {
UIGraphicsBeginPDFPage();
render.drawPage(at: i, in: UIGraphicsGetPDFContextBounds())
}
UIGraphicsEndPDFContext();
// 5. Save PDF file
guard let outputURL = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("output").appendingPathExtension("pdf")
else { fatalError("Destination URL not created") }
pdfData.write(to: outputURL, atomically: true)
print("open \(outputURL.path)") // command to open the generated file
@sllvn
Copy link

sllvn commented Oct 5, 2018

This is awesome. Thanks much.

A note for React Native folks: UIKit is not thread-safe, and React Native currently calls native module methods off main thread, so you'll want to request the main thread (as described or via DispatchQueue.main.async). Otherwise you'll get cryptic EXC_I386_BPT errors when instantiating your UIMarkupTextPrintFormatter.

@ddnn55
Copy link

ddnn55 commented Nov 11, 2018

Awesome, just one question... I'm setting page to 6 * 72 x 4 * 72 (6 inches wide by 4 inches tall). My content is cropped to that size, but the actual paper size in the PDF is 8.5x11. Do we know how to set the actual paper size?

@Jimenaleonbm
Copy link

Awesome, just one question... I'm setting page to 6 * 72 x 4 * 72 (6 inches wide by 4 inches tall). My content is cropped to that size, but the actual paper size in the PDF is 8.5x11. Do we know how to set the actual paper size?

Hi, how could you solve this?

@vixenaga
Copy link

Hi, do you know how to open a file after creating it? I tried this:
UIApplication.shared.open(outputURL, options: [:], completionHandler: { (success) in
Swift.print("Open url : (success)")
})
but I am getting false.

@GuzAlex
Copy link

GuzAlex commented Jan 8, 2020

Hi, who know how to edit pdf/doc file?

@Udit-sys
Copy link

Hi,

Actually my html content is cutting off on right?

Is there a way to set custom page for pdf...please see i dont require to print the pdf but just download it.

Thanks in advance.

@KaanYT
Copy link

KaanYT commented Aug 12, 2020

Objective-C Version

+(NSData*)htmlToPdf:(NSString*)html{
    //Formatter
    UIMarkupTextPrintFormatter * fmt = [[UIMarkupTextPrintFormatter alloc] initWithMarkupText:html];
    
    //Renderer
    UIPrintPageRenderer * render = [[UIPrintPageRenderer alloc] init];
    [render addPrintFormatter:fmt startingAtPageAtIndex:0];
    
    //Assign Printable Rect
    CGRect pageSize = CGRectMake(0, 0, 595.2, 841.8);// A4, 72 dpi
    [render setValue:[NSValue valueWithCGRect:pageSize] forKey:@"paperRect"];
    [render setValue:[NSValue valueWithCGRect:pageSize] forKey:@"printableRect"];
    
    //Create PDF Context and Draw
    NSMutableData* data = [[NSMutableData alloc] init];
    UIGraphicsBeginPDFContextToData(data, CGRectZero, NULL);
    
    for (int i=0; i<render.numberOfPages; i++) {
        UIGraphicsBeginPDFPage();
        [render drawPageAtIndex:i inRect: UIGraphicsGetPDFContextBounds()];
    }

    UIGraphicsEndPDFContext();

    return data;
}

@matrosovDev
Copy link

I also faced with image issue, just wonder if this resolved I've tried a few solutions but it still does not work for me. I tried to save image to the files and used base 64 image, but still with no luck

https://stackoverflow.com/questions/66251424/creating-pdf-file-with-uiimage-inserted-to-html-code

@Udit-sys
Copy link

Hey,
I think you need to use javascript with your HTML code to load image in web view and then create a pdf
Use evaluateJavaScript() to run javascript in web view

@matrosovDev
Copy link

Hey,
I think you need to use javascript with your HTML code to load image in web view and then create a pdf
Use evaluateJavaScript() to run javascript in web view

Now all works good! I used link above https://github.com/nyg/HTMLWithImagesToPDF in a wrong way. Image is in the PDF file now. thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment