Create PDF from UIView, WKWebView, and UITableView

Create PDF from UIView

You can easily create a PDF file from UIView. Create an Extension of UIView and add below code in your UIView Extension file.
Extension UIView {
    
    // Export pdf from Save pdf in drectory and return pdf file path
    func exportAsPdfFromView() -> String {
        
        let pdfPageFrame = self.bounds
        let pdfData = NSMutableData()
        UIGraphicsBeginPDFContextToData(pdfData, pdfPageFrame, nil)
        UIGraphicsBeginPDFPageWithInfo(pdfPageFrame, nil)
        guard let pdfContext = UIGraphicsGetCurrentContext() else { return "" }
        self.layer.render(in: pdfContext)
        UIGraphicsEndPDFContext()
        return self.saveViewPdf(data: pdfData)
        
    }
    
    // Save pdf file in document directory
    func saveViewPdf(data: NSMutableData) -> String {
        
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        let docDirectoryPath = paths[0]
        let pdfPath = docDirectoryPath.appendingPathComponent("viewPdf.pdf")
        if data.write(to: pdfPath, atomically: true) {
            return pdfPath.path
        } else {
            return ""
        }
    }
}
Now using above Extension you can export to PDF of any UIView and it will save PDF file in directory and return it’s path. Suppose you want to create a PDF from self.view then write below code.
let pdfFilePath = self.view.exportAsPdfFromView()
print(pdfFilePath)

Create PDF from WKWebView

We are going to create an Extension of WKWebView and Extension of UIPrintPageRenderer. With the help of UIPrintPageRenderer we will create NSMutableData to render PDF file from WKWebView. Add below Extensions in your file.

extension WKWebView {
    
    // Call this function when WKWebView finish loading
    func exportAsPdfFromWebView() -> String {
        let pdfData = createPdfFile(printFormatter: self.viewPrintFormatter())
        return self.saveWebViewPdf(data: pdfData)
    }
    
    func createPdfFile(printFormatter: UIViewPrintFormatter) -> NSMutableData {
        
        let originalBounds = self.bounds
        self.bounds = CGRect(x: originalBounds.origin.x, y: bounds.origin.y, width: self.bounds.size.width, height: self.scrollView.contentSize.height)
        let pdfPageFrame = CGRect(x: 0, y: 0, width: self.bounds.size.width, height: self.scrollView.contentSize.height)
        let printPageRenderer = UIPrintPageRenderer()
        printPageRenderer.addPrintFormatter(printFormatter, startingAtPageAt: 0)
        printPageRenderer.setValue(NSValue(cgRect: UIScreen.main.bounds), forKey: "paperRect")
        printPageRenderer.setValue(NSValue(cgRect: pdfPageFrame), forKey: "printableRect")
        self.bounds = originalBounds
        return printPageRenderer.generatePdfData()
    }
    
    // Save pdf file in document directory
    func saveWebViewPdf(data: NSMutableData) -> String {
        
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        let docDirectoryPath = paths[0]
        let pdfPath = docDirectoryPath.appendingPathComponent("webViewPdf.pdf")
        if data.write(to: pdfPath, atomically: true) {
            return pdfPath.path
        } else {
            return ""
        }
    }
}

extension UIPrintPageRenderer {
    
    func generatePdfData() -> NSMutableData {
        let pdfData = NSMutableData()
        UIGraphicsBeginPDFContextToData(pdfData, self.paperRect, nil)
        self.prepare(forDrawingPages: NSMakeRange(0, self.numberOfPages))
        let printRect = UIGraphicsGetPDFContextBounds()
        for pdfPage in 0..< self.numberOfPages {
            UIGraphicsBeginPDFPage()
            self.drawPage(at: pdfPage, in: printRect)
        }
        UIGraphicsEndPDFContext();
        return pdfData
    }
}
Now we can create PDF from any WKWebView. Write below code to create PDF file of WKWebView.
let pdfFilePath = self.webView.exportAsPdfFromWebView()
print(pdfFilePath)

Create PDF from UITableView

Again we will create an Extension of UITableView and using this Extension we can create PDF file of any UITableView
extension UITableView {
    
    // Export pdf from UITableView and save pdf in drectory and return pdf file path
    func exportAsPdfFromTable() -> String {
        
        let originalBounds = self.bounds
        self.bounds = CGRect(x:originalBounds.origin.x, y: originalBounds.origin.y, width: self.contentSize.width, height: self.contentSize.height)
        let pdfPageFrame = CGRect(x: 0, y: 0, width: self.bounds.size.width, height: self.contentSize.height)
        
        let pdfData = NSMutableData()
        UIGraphicsBeginPDFContextToData(pdfData, pdfPageFrame, nil)
        UIGraphicsBeginPDFPageWithInfo(pdfPageFrame, nil)
        guard let pdfContext = UIGraphicsGetCurrentContext() else { return "" }
        self.layer.render(in: pdfContext)
        UIGraphicsEndPDFContext()
        self.bounds = originalBounds
        // Save pdf data
        return self.saveTablePdf(data: pdfData)
        
    }
    
    // Save pdf file in document directory
    func saveTablePdf(data: NSMutableData) -> String {
        
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        let docDirectoryPath = paths[0]
        let pdfPath = docDirectoryPath.appendingPathComponent("tablePdf.pdf")
        if data.write(to: pdfPath, atomically: true) {
            return pdfPath.path
        } else {
            return ""
        }
    }
}
Now in order to generate PDF from UITableView write below code.
let pdfFilePath = self.tableView.exportAsPdfFromTable()
print(pdfFilePath)

Read next article: The dynamic height of UITextView inside UITableViewCell Swift

6 comments on “Create PDF from UIView, WKWebView, and UITableView

  1. Zyf

    The quality of the PDF saved is very low. How can i increase the quality of the PDFs ? And also how can i make a PDF with more than 1 page?

    Reply
  2. Ian

    This is really great but for what ever reason intermittently creates a blank pdf! does anyone know how to resolve this?

    Reply
  3. Salvatore

    Nice but

    The background of table view (or cell must be ignored)

    the pdf generated have a very big dimension (120 MB for me) it’s possible to resize? (maybe with a parameter)

    the pdf is not possible to share or show in UIDocumentPreview / uiactivity etc…

    There is a easy way to print or save correctly?

    Reply
  4. Marc

    This article is great. I’am new into XCode/Swift/iOS. I have one question, I am working on a tabbed app.
    I like to save all the tabbed Views to one pdf. With the sample above, I can save seperate views. Can
    you give me a hint how to accomplish this?

    Thanks and best regards,

    Marc

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *