Reputation: 19
I want to Print NSTableVIew data as multi page print preview but print preview shows only first few records rest pages are empty.I am using below code to print NStableView data.
let printInfo = NSPrintInfo.shared
printInfo.paperSize = NSSize(width: self.reporttableview.frame.width , height: 800.00)
printInfo.verticalPagination = .automatic
let operation: NSPrintOperation = NSPrintOperation(view: self.reporttableview, printInfo: printInfo)
operation.printPanel.options.insert([.showsPaperSize, .showsOrientation])
operation.run()
Above code working fine with minimum records like 30 -40 rows but when record is around 100 or more than 100 its only print first few records and rest pages are empty.Any help will be really appreciated.I have attached tableview and Print preview screen shots for better understanding.
I am not able to understand what I am doing wrong.
Upvotes: 0
Views: 265
Reputation: 81
I had the same problem. I believe it is caused by the method AppKit uses to display NSTableViews efficiently. This seems to optimise, i.e. reduce, the memory load of large NSTableViews by only generating display data for about 3 "pages" of the view. To get the entire NSTableView to print, set the NSTableView instance property var usesStaticContents: Bool { get set }
to true before printing (and return its value to false once printing is completed). I have tested this successfully on a table of 33 x A4 landscape pages and it works fine (although it takes ~5 seconds before the print panel is displayed).
Here is the code that worked for me:
struct ReportsDetailView: View {
@Binding var reportNodes: [ReportNode]
@State private var viewToPrint = NSView()
@State private var printing = false
var body: some View {
VStack {
ReportsDetailTableVC(reportNodes: $reportNodes, viewToPrint: $viewToPrint, printing: $printing)
HStack {
Spacer()
Button("Print Report") {
printing = true
let scale: CGFloat = 800/viewToPrint.frame.width
let printInfo = NSPrintInfo()
printInfo.horizontalPagination = .automatic
printInfo.verticalPagination = .automatic
printInfo.isVerticallyCentered = true
printInfo.isHorizontallyCentered = true
printInfo.printer = NSPrinter(name: NSPrinter.printerNames[0])!
printInfo.paperSize = NSSize(width: 595.28, height: 841.89)
printInfo.topMargin = 10
printInfo.bottomMargin = 10
printInfo.leftMargin = 10
printInfo.rightMargin = 10
printInfo.orientation = .landscape
printInfo.scalingFactor = scale
let printOperation = NSPrintOperation(view: viewToPrint, printInfo: printInfo)
printOperation.run()
printing = false
}
.disabled(printing)
}
.padding(10)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
struct ReportsDetailTableVC: NSViewControllerRepresentable {
@Environment(\.colorScheme) var colorScheme
@Binding var reportNodes: [ReportNode]
@Binding var viewToPrint: NSView
@Binding var printing: Bool
func makeNSViewController(context: Context) -> some NSViewController {
let reportsDetailVC = ReportsDetailTableViewController()
return reportsDetailVC
}
func updateNSViewController(_ nsViewController: NSViewControllerType, context: Context) {
guard let reportsDetailVC = nsViewController as? ReportsDetailTableViewController else {return}
reportsDetailVC.setContents(reportNodes: reportNodes)
if printing {
reportsDetailVC.tableView.scrollRowToVisible(0)
reportsDetailVC.tableView.usesStaticContents = true
reportsDetailVC.tableView.appearance = NSAppearance(named: .aqua)
reportsDetailVC.tableView.usesAlternatingRowBackgroundColors = false
}
else {
reportsDetailVC.tableView.usesStaticContents = false
reportsDetailVC.tableView.appearance = colorScheme == .light ? NSAppearance(named: .aqua) : NSAppearance(named: .darkAqua)
reportsDetailVC.tableView.usesAlternatingRowBackgroundColors = true
}
DispatchQueue.main.async {viewToPrint = reportsDetailVC.tableView}
}
}
Upvotes: 0