Create PDF from UIView
You can easily create a PDF file fromUIView
. 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 ofWKWebView
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 ofUITableView
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
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?
Perfectly composed content material, appreciate it for information .
This is really great but for what ever reason intermittently creates a blank pdf! does anyone know how to resolve this?
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?
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