代码之家  ›  专栏  ›  技术社区  ›  Trombone0904

将web视图内容另存为pdf文件

  •  9
  • Trombone0904  · 技术社区  · 7 年前

    注意:我正在为osx使用swift 4。 我想从网络视图生成pdf文件。

    如果我按下按钮,打印面板将打开,并准备以正确的格式打印我的WebView内容。

    这是我的打印代码:

    var webView = WebView()
    var htmlString = "MY HTML STRING"
    
    override func viewDidLoad() {
        webView.mainFrame.loadHTMLString(htmlString, baseURL: nil)
    }
    
    func webView(_ sender: WebView!, didFinishLoadFor frame: WebFrame!) {
    
        let printInfo = NSPrintInfo.shared
        printInfo.paperSize = NSMakeSize(595.22, 841.85)
        printInfo.isHorizontallyCentered = true
        printInfo.isVerticallyCentered = true
        printInfo.orientation = .portrait
        printInfo.topMargin = 50
        printInfo.rightMargin = 0
        printInfo.bottomMargin = 50
        printInfo.leftMargin = 0
        printInfo.verticalPagination = .autoPagination
        printInfo.horizontalPagination = .fitPagination
        //webView.mainFrame.frameView.printOperation(with: printInfo).run()
    
        let printOp: NSPrintOperation = NSPrintOperation(view: webView.mainFrame.frameView.documentView, printInfo: printInfo)
        printOp.showsPrintPanel = true
        printOp.showsProgressPanel = false
        printOp.run() 
    }
    

    enter image description here

    我试过这个:

    let pdfData = webView.mainFrame.frameView.documentView.dataWithPDF(inside: webView.mainFrame.frameView.documentView.frame)
    let document = PDFDocument(data: pdfData)
    let fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("myPDF.pdf")
    document?.write(to: fileURL)
    

    但我的pdf结果看起来很糟糕:

    enter image description here

    这是我的web视图结果的一部分:

    enter image description here

    这是我的打印预览/pdf文件/颜色丢失的结果,但现在到处都是。“徽标”(图片)将以颜色显示: enter image description here

    1 回复  |  直到 7 年前
        1
  •  6
  •   Charles Srstka    7 年前

    问题是 dataWithPDF 使用视图的当前帧来决定生成的PDF的宽度。自从你 WebView 你的应用程序中的框架可能比8.5/11英寸的页面更薄,你得到的PDF不够宽 调整 将框架的大小调整到合适的大小,制作PDF,然后将其调整回来,或者您可以创建一个新的框架 网络视图 ,将其渲染到屏幕外,将其设置为适当的大小,然后创建PDF。不过,这背后有点痛。如果有一种方法可以通过编程实现打印对话框中“PDF”按钮的功能,那岂不是太好了,因为打印系统会自动为您处理所有这些事情?

    事实证明你可以!但你必须深入到核心打印的文档记录不足的世界。

    func makePDF(at url: URL, for webView: WebView, printInfo: NSPrintInfo) throws {
        webView.preferences.shouldPrintBackgrounds = true
    
        guard let printOp = webView.mainFrame.frameView.printOperation(with: printInfo) else {
            throw MyPrintError.couldntGetPrintOperation // or something like this
        }
    
        let session = PMPrintSession(printOp.printInfo.pmPrintSession())
        let settings = PMPrintSettings(printOp.printInfo.pmPrintSettings())
    
        if PMSessionSetDestination(session,
                                   settings,
                                   PMDestinationType(kPMDestinationFile),
                                   kPMDocumentFormatPDF as CFString,
                                   url as CFURL) != noErr {
            throw MyPrintError.couldntSetDestination // or something like this
        }
    
        printOp.showsPrintPanel = false
        printOp.run()
    }
    

    关键是 PMSessionSetDestination 调用,它允许我们将打印会话配置为打印到PDF而不是实际打印机。然后我们就说 NSPrintOperation