You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Swift 5下如何将Office文档转为PDF并获取多格式文档页数

iOS Swift5 下获取Office文档页数的实现方案

核心思路

你之前通过WebKit的WebView直接提取页数返回0,是因为WebKit没有对外暴露直接读取Office文档分页的官方接口,内部渲染的分页信息无法直接获取。通过「WebView加载文档→原生渲染转PDF→读取PDF页数」的路径是目前无需引入第三方SDK的最稳定实现方案,兼容doc、docx、ppt、pptx、xls、xlsx所有主流Office格式。

完整实现代码

需要导入三个原生框架:WebKit、PDFKit、UIKit

import UIKit
import WebKit
import PDFKit

class OfficePageCounter: NSObject, WKNavigationDelegate {
    private var webView: WKWebView!
    private var completion: ((Int) -> Void)?
    
    override init() {
        super.init()
        let config = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: config)
        webView.navigationDelegate = self
    }
    
    /// 获取Office文档页数
    /// - Parameters:
    ///   - fileURL: 本地Office文件的沙盒URL
    ///   - completion: 回调返回页数,加载失败返回0
    func getPageCount(for fileURL: URL, completion: @escaping (Int) -> Void) {
        self.completion = completion
        let request = URLRequest(url: fileURL)
        webView.load(request)
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        // 延迟等待复杂文档渲染完成,可根据实际场景调整延迟时长
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
            guard let self = self else { return }
            let renderer = UIPrintPageRenderer()
            renderer.addPrintFormatter(webView.viewPrintFormatter(), startingAtPageAt: 0)
            
            // 定义A4纸标准尺寸,和Office默认分页规则对齐
            let a4PageRect = CGRect(x: 0, y: 0, width: 595.2, height: 841.8)
            renderer.setValue(NSValue(cgRect: a4PageRect), forKey: "paperRect")
            renderer.setValue(NSValue(cgRect: a4PageRect), forKey: "printableRect")
            
            // 生成PDF数据
            let pdfData = NSMutableData()
            UIGraphicsBeginPDFContextToData(pdfData, a4PageRect, nil)
            renderer.prepare(forDrawingPages: NSRange(location: 0, length: renderer.numberOfPages))
            for pageIndex in 0..<renderer.numberOfPages {
                UIGraphicsBeginPDFPage()
                renderer.drawPage(at: pageIndex, in: UIGraphicsGetPDFContextBounds())
            }
            UIGraphicsEndPDFContext()
            
            // 读取PDF页数
            if let pdfDocument = PDFDocument(data: pdfData as Data) {
                self.completion?(pdfDocument.pageCount)
            } else {
                self.completion?(0)
            }
        }
    }
    
    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        completion?(0)
    }
}

使用方法

  • 首先将目标Office文档下载到本地沙盒,获取本地文件URL(不支持直接加载远程URL)
  • 需要在调用处持有OfficePageCounter实例,避免异步回调过程中实例被提前释放,调用示例:
// 全局持有counter,避免提前释放
var pageCounterHolder: OfficePageCounter?

// 示例调用
if let localFileUrl = Bundle.main.url(forResource: "test", withExtension: "docx") {
    pageCounterHolder = OfficePageCounter()
    pageCounterHolder?.getPageCount(for: localFileUrl) { pageCount in
        print("文档页数为:\(pageCount)")
        // 用完可释放实例
        self.pageCounterHolder = nil
    }
}

注意事项

  • 支持iOS 11及以上系统版本
  • xls/xlsx类表格文档的分页规则和PC端Office的A4纸分页结果基本一致
  • 超大体积的Office文档可自行添加加载超时判断,避免长时间无回调
  • 如果不需要留存PDF文件,生成的PDF数据仅用于读取页数,不会占用额外的磁盘存储空间

内容的提问来源于stack exchange,提问作者Heyman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 05:36:04