|
| 1 | +import UIKit |
| 2 | + |
| 3 | +/// |
| 4 | +/// Reads the given HTML file and replaces `{{ABSOLUTE_PATH}}` and `{{BASE64_STRING}}` with proper values. |
| 5 | +/// |
| 6 | +/// - parameters: |
| 7 | +/// - htmlFile: The HTML file. |
| 8 | +/// |
| 9 | +func getHTML(from htmlFile: URL) -> String { |
| 10 | + |
| 11 | + guard var htmlContent = try? String(contentsOf: htmlFile) |
| 12 | + else { fatalError("Error getting HTML file content.") } |
| 13 | + |
| 14 | + guard let imgURL = Bundle.main.url(forResource: "apple", withExtension: "png") |
| 15 | + else { fatalError("Error locating image file.") } |
| 16 | + |
| 17 | + guard let base64String = try? Data(contentsOf: imgURL).base64EncodedString() |
| 18 | + else { fatalError("Error creating Base64-encoded string.") } |
| 19 | + |
| 20 | + return htmlContent |
| 21 | + .replacingOccurrences(of: "{{ABSOLUTE_PATH}}", with: imgURL.description) |
| 22 | + .replacingOccurrences(of: "{{BASE64_STRING}}", with: base64String) |
| 23 | +} |
| 24 | + |
| 25 | +/// |
| 26 | +/// Generates a PDF from the given HTML code and saves it to the given destination file. |
| 27 | +/// |
| 28 | +/// - parameters: |
| 29 | +/// - html: The HTML code. |
| 30 | +/// - destination: The URL indicating where to write the generated PDF file. |
| 31 | +/// |
| 32 | +func createPDF(with html: String, to destination: URL) { |
| 33 | + |
| 34 | + // create print formatter |
| 35 | + let printFormatter = UIMarkupTextPrintFormatter(markupText: html) |
| 36 | + |
| 37 | + // assign the print formatter to the print page renderer |
| 38 | + let renderer = UIPrintPageRenderer() |
| 39 | + renderer.addPrintFormatter(printFormatter, startingAtPageAt: 0) |
| 40 | + |
| 41 | + // assign paperRect and printableRect values |
| 42 | + let page = CGRect(x: 0, y: 0, width: 595.2, height: 841.8) // A4, 72 dpi |
| 43 | + renderer.setValue(page, forKey: "paperRect") |
| 44 | + renderer.setValue(page, forKey: "printableRect") |
| 45 | + |
| 46 | + // create pdf context and draw each page |
| 47 | + let pdfData = NSMutableData() |
| 48 | + UIGraphicsBeginPDFContextToData(pdfData, .zero, nil) |
| 49 | + |
| 50 | + for i in 0..<renderer.numberOfPages { |
| 51 | + UIGraphicsBeginPDFPage() |
| 52 | + renderer.drawPage(at: i, in: UIGraphicsGetPDFContextBounds()) |
| 53 | + } |
| 54 | + |
| 55 | + UIGraphicsEndPDFContext(); |
| 56 | + |
| 57 | + // save data to file |
| 58 | + do { |
| 59 | + try pdfData.write(to: destination, options: .atomic) |
| 60 | + print("open \(destination.path)") |
| 61 | + } |
| 62 | + catch { |
| 63 | + fatalError("Error writing PDF data to file: \(error)") |
| 64 | + } |
| 65 | +} |
| 66 | + |
| 67 | +/* Generating PDF. */ |
| 68 | + |
| 69 | +guard let htmlFile = Bundle.main.url(forResource: "index", withExtension: "html") |
| 70 | + else { fatalError("Error locating HTML file.") } |
| 71 | + |
| 72 | +let htmlContent = getHTML(from: htmlFile) |
| 73 | + |
| 74 | +guard let outputURL = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("generated.pdf") |
| 75 | + else { fatalError("Error getting user's document directory.") } |
| 76 | + |
| 77 | +createPDF(with: htmlContent, to: outputURL) |
0 commit comments