Create PDF from UIWebView

2.8k Views Asked by At

I'm having problem creating PDF from UIWebView.

        let render = UIPrintPageRenderer();      
        /* 1. pdf from webView */
        render.addPrintFormatter(webView.viewPrintFormatter(), startingAtPageAtIndex: 0);

        // 2. 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")

        // 3. 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();

        // 4. Save PDF file
        print("open \(path)");
        pdfData.writeToFile(path, atomically: true);

Everything work fine, but if I use background image inside the HTML, it will disappear. Anyone know what's wrong?

1

There are 1 best solutions below

0
On

First of all you need to create your html code :

var html = "<html><head><meta charset='UTF-8'></head><body>hello from html </body></html>"

than you need to instantiate your web view using the following :

let webView = UIWebView(frame: self.view.bounds)
self.view.addSubview(webView)
webView.delegate = self
webView.loadHTMLString(html, baseURL: nil)
// webView.isUserInteractionEnabled = true

aftr that you need to make your ViewController class implement UIWebViewDelegate and implement the method func webViewDidFinishLoad(_ webView: UIWebView) and finally add the following code inside webViewDidFinishLoad method

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()
}

So to resume the logic : 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.