I need to generate a report as pdf an print it. Im generating a view with all the information and converting it to pdf and then showing the pdf file in a UIWebView. But when I see the Pdf file in the UIWebView, the file is not complete (a big part of the right area and the bot area are cut). I don't know if my UIView is too big when I'm converting it to Pdf or the UIWebView is cutting it.
PDF Function
func createPDFfromUIView(aView: UIView) //-> UIImage
{
let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, aView.frame, nil)
UIGraphicsBeginPDFPage()
let pdfContext = UIGraphicsGetCurrentContext();
aView.layer.renderInContext(pdfContext!)
UIGraphicsEndPDFContext();
let documentsDirectory: NSString = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask,true)[0] as NSString
let dataPath = documentsDirectory.stringByAppendingPathComponent("/JamaWEpdf")
if (!NSFileManager.defaultManager().fileExistsAtPath(dataPath as String)) {
do{
try NSFileManager.defaultManager().createDirectoryAtPath(dataPath, withIntermediateDirectories: false, attributes: nil)
}
catch _{}
}
let filePath = "\(dataPath)entry\(entry1.entryId)pdf.pdf"
pdfData.writeToFile(filePath, atomically: true)
let webView = UIWebView()
webView.loadRequest(NSURLRequest(URL: NSURL(fileURLWithPath: filePath)))
webView.frame = self.view.frame
self.view.addSubview(webView)
}
I don't know if my approach is right. The UIView size is w: 2480 h: 3508.
I was generating the view programmatically so when this line was executed:
UIGraphicsBeginPDFContextToData(pdfData, aView.frame, nil)
the frame was not rendered or something. So instead I use a CGRect with the size I wanted and it work:
UIGraphicsBeginPDFContextToData(pdfData, CGRect(x: 0, y: 0, width: 2480, height: 3508), nil)
Related
I am working on the HtmltoPDF creation. It is working fine when some image URL but not working with my server image URL.
Working URL downloaded from the google
Issue in the server image URL
I have put here my code for the pdf generation. Please find it
func exportHTMLContentToPDF(HTMLContent: String) -> String {
let printPageRenderer = IPPrintPageRenderer()
let printFormatter = UIMarkupTextPrintFormatter(markupText: HTMLContent)
printPageRenderer.addPrintFormatter(printFormatter, startingAtPageAt: 0)
let pdfData = drawPDFUsingPrintPageRenderer(printPageRenderer: printPageRenderer)
let str = "\(Global.kretriveUserData().firstName!.firstCharacter!)\(Global.kretriveUserData().Name!.firstCharacter!)".uppercased()
pdfFilename = "\(getDocDir())/\(str + invoiceNumber!).pdf"
pdfData?.write(toFile: pdfFilename, atomically: true)
print(pdfFilename)
return pdfFilename
}
func drawPDFUsingPrintPageRenderer(printPageRenderer: UIPrintPageRenderer) -> NSData! {
let data = NSMutableData()
UIGraphicsBeginPDFContextToData(data, CGRect.zero, nil)
for i in 0..<printPageRenderer.numberOfPages {
UIGraphicsBeginPDFPage()
printPageRenderer.drawPage(at: i, in: UIGraphicsGetPDFContextBounds())
}
UIGraphicsEndPDFContext()
return data
}
func getDocDir() -> String {
return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
}
You can find a full demo here.
Thanks,
To generate a pdf from a webView you need to prepare your HTML code, create the WebView and inject the HTML code inside the webView and in webView didFinishLoading print the HTML content inside the pdf using the same width and height of the webView.
func webViewDidFinishLoad(_ webView: UIWebView) {
let render = UIPrintPageRenderer()
render.addPrintFormatter(webView.viewPrintFormatter(), startingAtPageAt: 0);
let page = CGRect(x: 0, y: 10, width: webView.frame.size.width, height: webView.frame.size.height) // take the size of the webView
let printable = page.insetBy(dx: 0, dy: 0)
render.setValue(NSValue(cgRect: page), forKey: "paperRect")
render.setValue(NSValue(cgRect: printable), forKey: "printableRect")
// 4. Create PDF context and draw
let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, CGRect.zero, nil)
for i in 1...render.numberOfPages {
UIGraphicsBeginPDFPage();
let bounds = UIGraphicsGetPDFContextBounds()
render.drawPage(at: i - 1, in: bounds)
}
UIGraphicsEndPDFContext();
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
print(documentsPath)
pdfData.write(toFile: "\(documentsPath)/pdfName.pdf", atomically: true)
self.pdfPath = "\(documentsPath)/pdfName.pdf"
self.pdfTitle = "pdfName"
self.performSegue(withIdentifier: "showPDFSegue", sender: nil)
webView.removeFromSuperview()
self.loadingScreenViewController.view.removeFromSuperview()
}
Happy coding:)
My Scenario, I am trying to save UITextView Text with Three format .pdf, .doc and .txt. Here, formate option user can choose based on alert option. Once Its saved need to show in Preview controller for file sharing. How to achieve this?
func createPDF(text:String, filename:String) {
// 1. Create Print Formatter with input text.
let formatter = UIMarkupTextPrintFormatter(markupText: text)
// 2. Add formatter with pageRender
let render = UIPrintPageRenderer()
render.addPrintFormatter(formatter, startingAtPageAt: 0)
// 3. Assign paperRect and printableRect
let page = CGRect(x: 0, y: 0, width: 595.2, height: 841.8) // A4, 72 dpi
let printable = page.insetBy(dx: 0, dy: 0)
render.setValue(NSValue(cgRect: page), forKey: "paperRect")
render.setValue(NSValue(cgRect: printable), forKey: "printableRect")
// 4. Create PDF context and draw
let rect = CGRect.zero
let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, rect, nil)
for i in 1...render.numberOfPages {
UIGraphicsBeginPDFPage();
let bounds = UIGraphicsGetPDFContextBounds()
render.drawPage(at: i - 1, in: bounds)
}
UIGraphicsEndPDFContext();
// 5. Save PDF file
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
pdfData.write(toFile: "\(documentsPath)/\(filename).pdf", atomically: true)
print("saved success:\(documentsPath)\(filename)")
listFiles()
}
Try the following code :)
let txtData = Data(textView.txt.utf8)
do {
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let filePath = (documentsPath as NSString).appendingPathComponent("\(filename).pdf")
let url = URL(fileURLWithPath: filePath)
// pdfData created by your code above
// txtData for ".txt"
pdfData.write(to: url)
let activityVC = UIActivityViewController(activityItems: [url], applicationActivities: nil)
// Use your desired viewController here, or just use the rootViewController
UIApplication.shared.keyWindow?.rootViewController?.presentViewController(activityVC, animated: true, completion: nil)
} catch (let error) {
print("\(error)")
}
If i understand correct you need show documents
You can do this with QLPreviewController
More info in -
https://developer.apple.com/documentation/quicklook
https://developer.apple.com/documentation/quicklook/qlpreviewcontroller#//apple_ref/occ/cl/QLPreviewController
https://medium.com/#garg.vivek/quick-display-documents-with-qlpreviewcontroller-eaca97928c7a
QLPreviewController have sharing control
I want to create a PDF file from the contents of a UIScrollView.
func createPdfFromView(aView: UIView, saveToDocumentsWithFileName fileName: String) {
let pdfData = NSMutableData()
let height = 1754.0
let width = 1240.0
UIGraphicsBeginPDFContextToData(pdfData, CGRect(x:-30, y:15,width:width,height:height) , nil)
UIGraphicsBeginPDFPage()
guard let pdfContext = UIGraphicsGetCurrentContext() else { return }
aView.layer.render(in: pdfContext)
UIGraphicsEndPDFContext()
if let documentDirectories = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first {
let documentsFileName = documentDirectories + "/" + fileName
debugPrint(documentsFileName)
pdfData.write(toFile: documentsFileName, atomically: true)
}
}
I would expect that the code generates a PDF oriented on the size of the content in the scrollview.
The code currently only generates a static PDF. If the content in the scrollview is bigger than the PDF page, the content is cut off.
func createPdfFromView()
{
// Set frame as per content of view
self.spreadsheetView.frame = CGRect(x: 0, y: 0, width: self.spreadsheetView.contentSize.width, height: self.spreadsheetView.contentSize.height)
let pdfPageBounds: CGRect = self.spreadsheetView.frame
let pdfData: NSMutableData = NSMutableData()
// Rendering spreadsheetView
UIGraphicsBeginPDFContextToData(pdfData, pdfPageBounds, nil)
UIGraphicsBeginPDFPageWithInfo(pdfPageBounds, nil)
self.spreadsheetView.layer.render(in: UIGraphicsGetCurrentContext()!)
UIGraphicsEndPDFContext()
let documentDirectories = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
let documentsFileName = documentDirectories! + "/" + "pdfName.pdf"
pdfData.write(toFile: documentsFileName, atomically: true)
print(documentsFileName)
// Reset spreadsheetView
self.spreadsheetView.frame = CGRect(x: 0, y: 64, width: self.view.frame.width, height: self.view.frame.height)
self.spreadsheetView.layoutSubviews()
self.spreadsheetView.layoutIfNeeded()
self.spreadsheetView.reloadData()}
Hope it will help you to create PDF from the spreadsheet.
Ref. Github code Link: SpreadsheetView
I could achieve this using this Cocoapods framework. In my case I wanted to make a PDF from Spreadsheet , so that this framework help me to add table with different column size and many more features which I had wanted from my data.
https://cocoapods.org/pods/SimplePDF
My app creates a pdf file when I hit enter button. I do this by the code below. At the moment I want to open the saved file automatically after saving.
The code for saving:
#IBAction func EnterButtonAction(_ sender: AnyObject) {
let html = "PDF FILE TITLE"
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: 1000) // A4, 72 dpi
let printable = page.insetBy(dx: 0, dy: 0)
render.setValue(NSValue(cgRect: page), forKey: "paperRect")
render.setValue(NSValue(cgRect: printable), forKey: "printableRect")
// 4. Create PDF context and draw
let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, CGRect.zero, nil)
for i in 1...render.numberOfPages {
UIGraphicsBeginPDFPage();
let bounds = UIGraphicsGetPDFContextBounds()
render.drawPage(at: i - 1, in: bounds)
}
UIGraphicsEndPDFContext();
// Save PDF file
let path = "\(NSTemporaryDirectory())MyAppFile.pdf"
pdfData.write(toFile: path, atomically: true)
print("open \(path)") // command to open the generated file
}
You can open your PDF file using UIDocumentInteractionController and find the below code:
func showFileWithPath(path: String){
let isFileFound:Bool? = NSFileManager.defaultManager().fileExistsAtPath(path)
if isFileFound == true{
let viewer = UIDocumentInteractionController(URL: NSURL(fileURLWithPath: path))
viewer.delegate = self
viewer.presentPreviewAnimated(true)
}
}
pdfData.write(toFile: path, atomically: true); is synchronous call, so you can write code to open file directly after this line, but first check if file is written successfully .
var success = pdfData.write(toFile: path, atomically: true);
if success {
//Write code to open file in Webview or UIDocumentInteractionController
}
I can create pdf file but I can't find the created file on iPhone device. When I run it on simulator it's possible to find directory where it saved. Where do I have to save it to preview on iPhone?
This is the code for creating pdf file:
func createPDF() {
let html = "<b>Hello <i>World!</i></b> <p>Generate PDF file from HTML in Swift</p>"
let fmt = UIMarkupTextPrintFormatter(markupText: html)
// 2. Assign print formatter to UIPrintPageRenderer
let render = UIPrintPageRenderer()
render.addPrintFormatter(fmt, startingAtPageAtIndex: 0)
// 3. Assign paperRect and printableRect
let page = CGRect(x: 0, y: 0, width: 595.2, height: 841.8) // A4, 72 dpi
let printable = CGRectInset(page, 0, 0)
render.setValue(NSValue(CGRect: page), forKey: "paperRect")
render.setValue(NSValue(CGRect: printable), forKey: "printableRect")
// 4. Create PDF context and draw
let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, CGRectZero, nil)
for i in 1...render.numberOfPages() {
UIGraphicsBeginPDFPage();
let bounds = UIGraphicsGetPDFContextBounds()
render.drawPageAtIndex(i - 1, inRect: bounds)
}
UIGraphicsEndPDFContext();
// 5. Save PDF file
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
pdfData.writeToFile("\(documentsPath)/file.pdf", atomically: true)
}
If you want to preview it, you need to either renter in in your own view in your own app, or otherwise share that pdf to other app, like share it via email, whatsapp, pages app or any other app.
For sharing that pdf, you can use UIActivityViewController.
Here, I am adding code for using the same with objective-c, you can convert it into swift as it is needed.
NSString *pdfFilePath = [documentsPath stringByAppendingPathComponent:#"file.pdf"];
NSURL *URL = [NSURL fileURLWithPath:pdfFilePath];
UIActivityViewController *activityViewController =
[[UIActivityViewController alloc] initWithActivityItems:#[#"My PDF File", URL]
applicationActivities:nil];
[self presentViewController:activityViewController
animated:YES
completion:^{
}];
Swift 3.0 code will be like:
let pdfFilePath = "path to file.pdf";
let url = NSURL.fileURL(withPath: pdfFilePath);
let activityVC = UIActivityViewController(activityItems: ["My Pdf File",url], applicationActivities: nil)
self.present(activityVC, animated: true, completion: nil);
Use
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] + "/file.pdf"
let myRequest = URLRequest(url: URL(fileURLWithPath: documentsPath))
webView.loadRequest(myRequest)
You can display the contents of the pdf in UIWebView.