在 WKWebView 中加载 Microsoft Office 文档

2024-05-01

我已经使用 UIWebView 在我的应用程序中显示 Microsoft Office 文档(Word、PowerPoint、Excel)一段时间了,但 Apple 最近已弃用 UIWebView 类。我正在尝试切换到 WKWebView,但 Word、Excel 和 Powerpoint 文档在 WKWebView 中无法正确呈现。

使用 UIWebView 显示 Excel 文档(效果很好):

let data: Data
//data is assigned bytes of Excel file
let webView = UIWebView()
webView.load(data, mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", textEncodingName: "UTF-8", baseURL: Bundle.main.bundleURL)

尝试使用 WKWebView 做同样的事情(显示一堆无意义的字符而不是 Excel 文件):

let data: Data
//data is assigned bytes of Excel file
let webView = WKWebView.init()
webView.load(data, mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", characterEncodingName: "UTF-8", baseURL: Bundle.main.bundleURL)

由于我的用例的性质,出于安全原因,我无法将数据保存到磁盘,因此我无法使用如下方法:

webView.loadFileURL(<#T##URL: URL##URL#>, allowingReadAccessTo: <#T##URL#>)

我也无法使用 QuickLook (QLPreviewController),因为它再次需要 URL。

-------------------------------------------------- - - - - - - -编辑 - - - - - - - - - - - - - - - - - - --------------------

我也知道这种通过字符串 URL 传递数据的方法,但除非有人能证明数据从未写入磁盘,否则我不能接受它作为答案:

let data: Data
//data is assigned bytes of Excel file
let webView = WKWebView.init()
let urlStr = "data:\(fileTypeInfo.mimeType);base64," + data.base64EncodedString()
let url = URL(string: urlStr)!
let request = URLRequest(url: url)
webView.load(request)

这感觉像是 WKWebView.load(_ data: Data, mimeType MIMEType: String, characterEncodingName: String, baseURL: URL) -> WKNavigation? 中的错误。它应该按照我们尝试使用它的方式工作,但我们是如何解决这个问题的:

声明您的 WKWebView 和自定义方案名称

let webView: WKWebView
let customSchemeName = "custom-scheme-name"

创建 WKURLSchemeHandler 的子类。我们使用 webView 在 webView 的生命周期中显示单个文档(PDF、Word、PowerPoint 或 Excel),因此我们将该文档作为 Data 和 FileTypeInfo 传递,FileTypeInfo 是我们创建的具有文件 MIME 类型的自定义类除此之外,在 WKURLSchemeHandler 的 init 中。

private class ExampleWKURLSchemeHandler: NSObject, WKURLSchemeHandler {

private let data: Data
private let fileTypeInfo: FileTypeInfo

init(data: Data, fileTypeInfo: FileTypeInfo) {
    self.data = data
    self.fileTypeInfo = fileTypeInfo
    super.init()
}

func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
    if let url = urlSchemeTask.request.url, let scheme = url.scheme, scheme == customSchemeName {
        let response = URLResponse.init(url: url, mimeType: fileTypeInfo.mimeType, expectedContentLength: data.count, textEncodingName: nil)

        urlSchemeTask.didReceive(response)
        urlSchemeTask.didReceive(data)
        urlSchemeTask.didFinish()
    }
}

func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {
    //any teardown code you may need
}

}

使用您刚刚创建的自定义方案处理程序类实例化您的 webView:

let webViewConfiguration = WKWebViewConfiguration()
let webViewSchemeHandler = ExampleWKURLSchemeHandler.init(data: data, fileTypeInfo: fileTypeInfo)
webViewConfiguration.setURLSchemeHandler(webViewSchemeHandler, forURLScheme: customSchemeName)
self.webView = WKWebView.init(frame: .zero, configuration: webViewConfiguration)

告诉 webView 使用与您的自定义方案匹配的 URL 加载文档。您可以在 url 中的 customSchemeName 前缀之后传递任何您想要的内容,但对于我们的用例,我们不需要这样做,因为我们已经传递了想要在 WKSchemeHandler 的初始化程序中显示的文档:

guard let url = URL.init(string: "\(customSchemeName):/123") else {
            fatalError()
        }
webView.load(URLRequest.init(url: url))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 WKWebView 中加载 Microsoft Office 文档 的相关文章

随机推荐