6

Swift 3.0でhtmlコンテンツからpdfファイルを作成しています:

/**
 *
 */
func exportHtmlContentToPDF(HTMLContent: String, filePath: String) {
    // let webView = UIWebView(frame: CGRect(x: 0, y: 0, width: 694, height: 603));

    // webView.loadHTMLString(HTMLContent, baseURL: nil);

    let pdfPrinter = PDFPrinter();
    let printFormatter = UIMarkupTextPrintFormatter(markupText: HTMLContent);
    // let printFormatter = webView.viewPrintFormatter();

    pdfPrinter.addPrintFormatter(printFormatter, startingAtPageAt: 0);

    let pdfData = self.drawPDFUsingPrintPageRenderer(printPageRenderer: pdfPrinter);

    pdfData?.write(toFile: filePath, atomically: true);
}

/**
 *
 */
func drawPDFUsingPrintPageRenderer(printPageRenderer: UIPrintPageRenderer) -> NSData! {
    let data = NSMutableData();

    UIGraphicsBeginPDFContextToData(data, CGRect.zero, nil);

    printPageRenderer.prepare(forDrawingPages: NSMakeRange(0, printPageRenderer.numberOfPages));

    let bounds = UIGraphicsGetPDFContextBounds();

    for i in 0...(printPageRenderer.numberOfPages - 1) {
        UIGraphicsBeginPDFPage();

        printPageRenderer.drawPage(at: i, in: bounds);
    }

    UIGraphicsEndPDFContext();

    return data;
}

私のbase64でエンコードされた画像を除いて、すべてがうまくレンダリングされます。WebView または Safari または Chrome ブラウザー内の HTML コンテンツ自体が正しく表示され、すべての画像が正しく表示されます。しかし、画像がpdfにレンダリングされることはありません。

画像がレンダリングされないのはなぜですか?どうすればレンダリングできますか?

4

2 に答える 2

6

これは、WebKit が最初に HTML を DOM に解析し、複数のイベント ループ サイクルでコンテンツをレンダリングするために発生します。したがって、ページ DOM の準備が整うだけでなく、リソースの読み込みが完了するまで待つ必要があります。また、お勧めのように、webview が最初に読み込まれるようにコードをリファクタリングする必要があり、その内容をエクスポートするだけです。

エクスポートを開始する正確な時間を決定するために、Web ビューで DOM ドキュメントの状態を観察できます。これを行うには複数の方法がありますが、私が見つけた最も読みやすいオプションは、関連する Objective-C の質問への回答のポートです。UIWebViewDelegateの実装でwebViewDidFinishLoadは、監視するために次の方法で実装しますdocument.readyState

    func webViewDidFinishLoad(_ webView: UIWebView) {

        guard let readyState = webView.stringByEvaluatingJavaScript(from: "document.readyState"),
            readyState == "complete" else
        {
            // document not yet parsed, or resources not yet loaded.
            return
        }

        // This is the last webViewDidFinishLoad call --> export.
        //
        // There is a problem with this method if you have JS code loading more content:
        // in that case -webViewDidFinishLoad can get called again still after document.readyState has already been in state 'complete' once or more.
        self.exportHtmlContentToPDF(…)
    }
于 2016-10-29T16:04:48.167 に答える
4

解決策を見つけました!

PDF へのエクスポートは、レンダリング プロセスが完了する前に行われます。非常に小さな画像を入れると、PDF に表示されます。画像が大きすぎると、レンダリング プロセスに時間がかかりすぎますが、PDF エクスポートはレンダリングが完了するのを待ちません。

だから私がそれを機能させるためにしたことは次のとおりです:

PDF にエクスポートする前に、HTML の結果を WebView に表示します。WebView はすべてを正しくレンダリングしており、PDF へのエクスポートを押すと、PDF がすべての画像とともに正しく表示されます。

したがって、レンダリング プロセスが完了するまで待機するように PDF Exporter に指示する方法がないため、これは大きな遅延であると思います。

于 2016-10-28T09:47:36.793 に答える