如何在 Swift 中向 MacOS 打印添加页眉和页脚?

问题描述 投票:0回答:1

我有一个 Mac 应用程序,可以打印一些 HTML。该部分工作正常,我弹出打印对话框并可以打印输出。但是,输出需要添加页眉和页脚(标题和页码),但我对如何执行此操作感到困惑。

我现有的打印代码如下所示:

public class HTMLPrintView: NSView {
    var webView: WKWebView
    
    public override init(frame frameRect: NSRect) {
        webView = WKWebView(frame: frameRect)
        super.init(frame: frameRect)
        addSubview(webView)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    public func printView(htmlContent: String, window parentWindow: NSWindow) {
        let webView = WKWebView(frame: .zero)
        webView.loadHTMLString(htmlContent, baseURL: nil)
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            let printInfo = NSPrintInfo()
            printInfo.horizontalPagination = .fit
            printInfo.verticalPagination = .fit
            printInfo.topMargin = 40
            printInfo.bottomMargin = 60
            printInfo.leftMargin = 40
            printInfo.rightMargin = 40
            printInfo.isVerticallyCentered = true
            printInfo.isHorizontallyCentered = true
            
            let printOperation = webView.printOperation(with: printInfo)
            
            printOperation.printPanel.options.insert(.showsPaperSize)
            printOperation.printPanel.options.insert(.showsOrientation)
            printOperation.printPanel.options.insert(.showsPreview)
            printOperation.view?.frame = NSRect(x: 0.0, y: 0.0, width: 300.0, height: 300.0)
            
            printOperation.runModal(for: parentWindow, delegate: self, didRun: nil, contextInfo: nil)
        }
    }
}

我创建了 HTMLPrintView 的实例并调用 printView 函数。

我尝试过重写drawPageBorder,但这似乎没有被调用。

遗憾的是,我发现有关 Mac 应用程序中打印的信息非常少。这是一个基于 SwiftUI 的应用程序,打印在视图模型中完成。

关于如何获取页眉和页脚有什么建议吗?

谢谢

swift macos printing header
1个回答
0
投票

我对此进行了一番尝试,并找到了一个可行的(如果不是优雅的)解决方案。代码如下。为了让事情变得更容易,我添加了一个结构体来为我的打印例程提供选项:

public struct PrintOptions {
    var header: String
    var footer: String
    var htmlContent: String
}

打印类现在是 WKWebView 的子类并覆盖了drawBorder函数:

public class HTMLPrintView: WKWebView {
    var pop: NSPrintOperation?
    var printOptions: PrintOptions?
    
    public override func drawPageBorder(with borderSize: NSSize) {
        
        super.drawPageBorder(with: borderSize)

        guard let pop,
              let printOptions
        else { return }
        
        // Drawing the header
        let headerAttributes: [NSAttributedString.Key: Any] = [
            .font: NSFont.systemFont(ofSize: 10),
            .foregroundColor: NSColor.black
        ]
        let headerString = NSAttributedString(string: printOptions.header, attributes: headerAttributes)
        headerString.draw(at: NSPoint(x: 30, y: borderSize.height - 50))
        
        // Drawing the footer
        let footerAttributes: [NSAttributedString.Key: Any] = [
            .font: NSFont.systemFont(ofSize: 10),
            .foregroundColor: NSColor.black
        ]
        
        let footerString = NSAttributedString(string: printOptions.footer,
                                              attributes: footerAttributes)
        footerString.draw(at: NSPoint(x: 30, y: 30))
        
        let pageString = NSAttributedString(string: "Page \(pop.currentPage)",
                                              attributes: footerAttributes)
        pageString.draw(at: NSPoint(x: borderSize.width - 80, y: 30))
    }

    public func printView(printOptions: PrintOptions, window parentWindow: NSWindow) {
        loadHTMLString(printOptions.htmlContent, baseURL: nil)

        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            let printInfo = NSPrintInfo()
            printInfo.horizontalPagination = .fit
            printInfo.verticalPagination = .fit
            printInfo.topMargin = 60
            printInfo.bottomMargin = 60
            printInfo.leftMargin = 40
            printInfo.rightMargin = 40
            printInfo.isVerticallyCentered = false
            printInfo.isHorizontallyCentered = false
            
            self.pop = self.printOperation(with: printInfo)
            self.printOptions = printOptions
            
            self.pop!.printPanel.options.insert(.showsPaperSize)
            self.pop!.printPanel.options.insert(.showsOrientation)
            self.pop!.printPanel.options.insert(.showsPreview)
            self.pop!.view?.frame = NSRect(x: 0.0, y: 0.0, width: 300.0, height: 900.0)
            
            self.pop!.runModal(
                for: parentWindow,
                delegate: self,
                didRun: nil,
                contextInfo: nil
            )
        }
    }
}

当我打印 HTML 时,它现在会显示页面内容并添加我想要的页眉和页脚。它需要一些整理,但它是一段功能正常的代码,所以是一个很好的起点。

© www.soinside.com 2019 - 2024. All rights reserved.