Rendering html pdf report for printing from UIWebView
HTML in UIWebView on iOS is rendered at 72dpi - it's fine for displaying on screen but when you generate .pdf file for printing using UIGraphicsBeginPDFContextToData, the end result will be .pdf file with 72dpi and it will not look nice when printed (heavily pixelized).
The trick is to :
1) scale everything in your HTML report 4 times bigger (I do this by css selctor sizes beeing defined as % of body size which is only parameter passed to report) and load it in UIWebView. See example of report css/html
2) create pdf by rendering UIWebView using 2480x3540 page (A4 in 300dpi)
3) in renderer scale down end result
Use of renderer (save NSData in pdf file).
private func printablePdfData(webView: UIWebView) -> NSData {
let A4Size = CGSizeMake(2480, 3504) // A4 in pixels at 300dpi
let renderer = PRV300dpiPrintRenderer()
let formatter = webView.viewPrintFormatter()
formatter.perPageContentInsets = UIEdgeInsetsZero
renderer.addPrintFormatter(formatter, startingAtPageAtIndex: 0)
let topPadding: CGFloat = 115.0
let bottomPadding: CGFloat = 117.0
let leftPadding: CGFloat = 100.0
let rightPadding: CGFloat = 100.0
let printableRect = CGRectMake(leftPadding, topPadding, A4Size.width - leftPadding - rightPadding, A4Size.height - topPadding - bottomPadding)
let A4Rect = CGRectMake(0, 0, A4Size.width, A4Size.height)
renderer.setValue(NSValue.init(CGRect: A4Rect), forKey: "paperRect")
renderer.setValue(NSValue.init(CGRect: printableRect), forKey: "printableRect")
let data = renderer.pdfData()
return data
}
Renderer class itself
class PRV300dpiPrintRenderer : UIPrintPageRenderer {
func pdfData() -> NSData {
let data = NSMutableData()
UIGraphicsBeginPDFContextToData(data, self.paperRect, nil)
UIColor.whiteColor().set();
let pdfContext = UIGraphicsGetCurrentContext()
CGContextSaveGState(pdfContext)
CGContextConcatCTM(pdfContext,CGAffineTransformMakeScale(72/300, 72/300)) // scale down to improve dpi from screen 72dpi to printable 300dpi
self.prepareForDrawingPages(NSRange.init(0...self.numberOfPages()))
let bounds = UIGraphicsGetPDFContextBounds()
for i in 0..<self.numberOfPages() {
UIGraphicsBeginPDFPage();
self.drawPageAtIndex(i, inRect: bounds)
}
CGContextRestoreGState(pdfContext)
UIGraphicsEndPDFContext();
return data
}
}
Written by xjki
Related protips
Have a fresh tip? Share with Coderwall community!
Post
Post a tip
Best
#Pdf
Authors
Sponsored by #native_company# — Learn More
#native_title#
#native_desc#