在 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 中加载

iframe 未在 WKWebview 中加载

在 WKWebView 中加载本地文件在设备中不起作用

WKWebView 无法在 HTML 中加载本地资源

iOS:如何在 webview 或 wkwebview 中加载动画 webp 图像

如果没有在 Swift 中加载 URL,如何使 WKWebView 不可滚动?