LoginSignup
7
8

More than 5 years have passed since last update.

WKWebViewにHTML表示させ、PDF化する(Swift2.2, XCode7.3.1)

Posted at

業務でHTMLファイルをPDF化する必要があったのでメモしておきます。

画面

スクリーンショット 2016-05-19 12.22.14.jpg
スクリーンショット 2016-05-19 12.22.26.jpg

コード

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate, UIScrollViewDelegate {
    private var subView: UIView!
    private var webView: WKWebView!

    override func viewDidLoad()
    {
        super.viewDidLoad()

        let size = view.frame.size
        subView = UIView(frame: CGRectMake(0, 0, size.width, size.height - 50))

        let btn = UIButton(type: .System)
        btn.frame = CGRectMake(0, size.height - 50, 90, 40)
        btn.setTitle("set HTML", forState: .Normal)
        btn.addTarget(self, action: #selector(ViewController.tapBtn(_:)), forControlEvents: .TouchUpInside)

        let btn2 = UIButton(type: .System)
        btn2.frame = CGRectMake(size.width * 0.35, size.height - 50, 90, 40)
        btn2.setTitle("set from web", forState: .Normal)
        btn2.addTarget(self, action: #selector(ViewController.tapBtn2(_:)), forControlEvents: .TouchUpInside)

        let btn3 = UIButton(type: .System)
        btn3.frame = CGRectMake(size.width * 0.7, size.height - 50, 90, 40)
        btn3.setTitle("create pdf", forState: .Normal)
        btn3.addTarget(self, action: #selector(ViewController.tapBtn3(_:)), forControlEvents: .TouchUpInside)

        view.addSubview(subView)
        view.addSubview(btn)
        view.addSubview(btn2)
        view.addSubview(btn3)

        webView = WKWebView()
        setupSubViews(subView)
    }

    internal func tapBtn(sender: UIButton) {
//        webView.loadHTMLString(getStrFromFile("test.html"), baseURL: nil)
        webView.loadHTMLString("hoge<br>piyo<br>foo<br>bar<br>hogeeeeeeeeeeeeeeeee", baseURL: nil)
    }

    internal func tapBtn2(sender: UIButton) {
        let req = NSURLRequest(URL: NSURL(string:"http://www.yahoo.co.jp/")!)
        webView.loadRequest(req)
    }

    internal func tapBtn3(sender: UIButton) {
        let path = NSHomeDirectory().stringByAppendingString("/hoge.pdf")
        PDFMaker.make([webView], path: path)
    }


    private func setupSubViews(v: UIView)
    {
//        webView.navigationDelegate = self
//        webView.scrollView.delegate = self
        webView.translatesAutoresizingMaskIntoConstraints = false
        v.addSubview(webView)
        var viewBindingsDict = [String: AnyObject]()
        viewBindingsDict["webView"] = webView
        v.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[webView]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: viewBindingsDict))
        v.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[webView]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: viewBindingsDict))
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // プロジェクトに追加したローカルファイルの文字列取得
    private func getStrFromFile(fname: String) -> String {
        var ret = ""
        var path = NSString(string: fname)
        // Encode 日本語ファイル対応
        path = path.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
        let ext = path.pathExtension
        let filename = path.stringByDeletingPathExtension
        do {
            if let path = NSBundle.mainBundle().pathForResource(filename, ofType: ext) {
                ret = try String(contentsOfFile: path, encoding: NSUTF8StringEncoding)
            }
        } catch {
            print("error getStrFromFile")
        }
        return ret
    }
}

// PDF作成クラス
class PDFMaker {
    private class func renderViews(views: [UIView]) {
        guard let context = UIGraphicsGetCurrentContext() else {
            return
        }
        views.forEach {
            if let scrollView = $0 as? UIScrollView {
                let tmpInfo = (offset: scrollView.contentOffset, frame: scrollView.frame)
                scrollView.contentOffset = CGPointZero
                scrollView.frame = CGRect(origin: CGPointZero, size: scrollView.contentSize)
                UIGraphicsBeginPDFPageWithInfo(scrollView.frame, nil)
                $0.layer.renderInContext(context)
                scrollView.frame = tmpInfo.frame
                scrollView.contentOffset = tmpInfo.offset
            } else {
                UIGraphicsBeginPDFPageWithInfo($0.bounds, nil)
                $0.layer.renderInContext(context)
            }
        }
    }

    class func make(views: [UIView], path: String) {
        UIGraphicsBeginPDFContextToFile(path, CGRectZero, nil)
        renderViews(views)
        UIGraphicsEndPDFContext()
    }

    class func make(views: [UIView]) -> NSData {
        let data = NSMutableData()
        UIGraphicsBeginPDFContextToData(data, CGRectZero, nil)
        renderViews(views)
        UIGraphicsEndPDFContext()
        return data
    }
}

作成したPDFを探す

シミュレータの場合

➜  ~ find ~/Library/Developer/CoreSimulator/Devices -name "hoge.pdf"
7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8