Swift: 使用 WKWebView 的 createPdf 创建 pdf

Swift: create pdf with WKWebView's createPdf

编辑:

找到了问题 2 的解决方案(给人的印象是问题 1 没有简单、开箱即用的解决方案)我决定关闭这个问题,而是专门为分页问题。


我有两个关于 WKWebView 的问题 createPDF(configuration:completionHandler:):

  1. 没有分页(我知道这个问题已经被其他人提出,而且似乎没有自动解决这个问题的方法——我想分页将是一项手动工作……)
  2. 我加载的 html 似乎正在用新行替换空格

下面的代码……

import SwiftUI
import WebKit

@main
struct PdfCreatorSOApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    var body: some View {
        Button("Create PDF") {
            savePdf()
        }
            .padding()
    }
    
    private func savePdf() {
        if let downloadDir = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first {
            let savePath = downloadDir.appendingPathComponent("swiftPdf").appendingPathExtension("pdf")
            
            let webViewConfiguration = WKWebViewConfiguration()//do I need to set s.th. here?
            
            let webView = WKWebView(frame: .zero, configuration: webViewConfiguration)
            
            let pdfConfiguration = WKPDFConfiguration()
            pdfConfiguration.rect = CGRect(x: 0, y: 0, width: 595.28, height: 841.89)
            
            webView.loadHTMLString(html, baseURL: nil)
            
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                webView.createPDF(configuration: pdfConfiguration) { result in
                    switch result {
                    
                    case .success(let data):
                        do {
                            try data.write(to: savePath)
                            print("Successfully created and saved pdf…")
                        } catch let error {
                            print("Could not _save_ pdf: \(error)")
                        }
                    case .failure(let error):
                        print("Could not create pdf: \(error)")
                    }
                }
            }
        }
    }
}

let html = """
<html>
<body>
<h1>Some Title</h1>
<p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tellus integer feugiat scelerisque varius. Nunc faucibus a pellentesque sit. Sagittis vitae et leo duis. Posuere lorem ipsum dolor sit amet consectetur. Porta non pulvinar neque laoreet suspendisse interdum. Dui faucibus in ornare quam viverra orci. Nulla facilisi etiam dignissim diam quis enim. Elementum pulvinar etiam non quam lacus suspendisse. Donec enim diam vulputate ut pharetra sit amet aliquam. Nunc mattis enim ut tellus elementum sagittis vitae. Vitae semper quis lectus nulla at volutpat diam ut. Enim eu turpis egestas pretium aenean pharetra magna ac.

    Cras sed felis eget velit aliquet sagittis id consectetur purus. Urna nunc id cursus metus aliquam eleifend mi. Interdum varius sit amet mattis vulputate enim nulla aliquet. At risus viverra adipiscing at in tellus integer feugiat. Dolor purus non enim praesent elementum facilisis leo vel fringilla. Interdum velit euismod in pellentesque massa placerat duis ultricies. Amet facilisis magna etiam tempor orci eu. Proin fermentum leo vel orci porta non pulvinar neque. Et magnis dis parturient montes nascetur ridiculus mus mauris vitae. Sagittis orci a scelerisque purus.
</p>
</body>
</html>
"""

…产生这个输出:

我的 WKWebViewConfiguration() 中是否缺少某些内容?

已编辑:

这只是一个猜测,但我不认为它是用换行符替换空格。它把它认为是一个窄网页的内容包装得尽可能窄(每个字)。

尝试调整 webView 的框架大小,看看是否有帮助?

let webView = WKWebView(frame: .zero,... // per comments this didn't help.

或通过CSS调整网页大小:

<p> <div **style='width: 600'**> lorem.... </div> // per comments this did