在 WKWebView 中加载 Microsoft Office 文档
Posted
技术标签:
【中文标题】在 WKWebView 中加载 Microsoft Office 文档【英文标题】:Loading Microsoft Office documents in WKWebView 【发布时间】:2019-09-03 16:22:39 【问题描述】:一段时间以来,我一直在使用 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)
【问题讨论】:
你可以在office在线编辑器中复制过去吗? 你有没有想过这个问题? 【参考方案1】:这感觉像是 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 传递,这是我们创建的具有文件的 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 加载文档。您可以在 customSchemeName 前缀之后在 url 中传递任何您想要的内容,但对于我们的用例,我们不需要,因为我们已经传递了我们想要在 WKSchemeHandler 的初始化程序中显示的文档:
guard let url = URL.init(string: "\(customSchemeName):/123") else
fatalError()
webView.load(URLRequest.init(url: url))
【讨论】:
嗨,Alec,我也有同样的问题...当我尝试通过字符串加载请求时,它会出现 912 错误...您能解决您的问题吗? 嘿 Steven,是的,我上面概述的代码对我们有用。我们没有遇到 912 错误。如果您发布您的代码,我可以尝试找到问题。以上是关于在 WKWebView 中加载 Microsoft Office 文档的主要内容,如果未能解决你的问题,请参考以下文章
检测页面是不是在 JavaScript 中的 WKWebView 中加载