Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

DavidCar

macrumors 6502a
Original poster
Jan 19, 2004
525
0
This is actually my answer to this question on Cocoa-Dev, but I couldn't see how to post a reply there. The existing replies mostly used HTML, and I didn't like that approach. I also couldn't find an answer I liked elsewhere on the internet.

http://lists.apple.com/archives/Cocoa-dev/2007/Jan/msg00801.html

I didn't want to learn HTML to print tabular data. This is the approach I took.

Essentially, I have a separate invisible window with a copy of the displayed NSTableView nested inside a custom NSView called MyPrintableBox. When MyPrintableBox is asked if it knowsPageRange, it calculates the needed pages from the number of rows in the table. When asked for RectForPage it returns the bounds rect but saves the page number for use in the dataSource methods. The dataSource method calls to MyPrintableBox use the dataSource methods of the displayed table to obtain the required data. Some NSTextFields associated with the displayed table needed to be duplicated near the invisible printed table, and these were updated at the time MyPrintableBox was passed to the print method. Some code here was only used while I was testing the approach with the printable window set as being visible. Of course, an NSView could be used instead of an NSBox,

I like this approach because I can initially use the same IB NSTableView and the dataSource methods used for the displayed table. I can later customize the appearance of the printed table to optimize it's printed appearance.

Code:
// Try box size w:600 h:760

@interface MyPrintableBox : NSBox {
	int rows, pages, pageNum;
	IBOutlet NSTextField *pageDisplay;
	IBOutlet NSWindowController *dataSourceWindow;
	IBOutlet NSTableView *PrintedTable;
	BOOL doingPages;
}
@end

@implementation MyPrintableBox

// The print method in MyDocument requests a printable NSView from MyWindow.
// MyWindow Nib contains an extra invisible window with a copy of the displayed table nested
// within an NSBox of this custom class, MyPrintableBox.  MyWindow returns MyPrintableBox
// as the printable NSView requested by MyDocument.  MyWindow updates some duplicate
// NSTextFields in myPrintableBox before filling the request.
// The dataSource for the invisible table is MyPrintableBox.
// The dataSource for the displayed table is MyWindow, connected here to dataSourceWindow

int rowsPerPage = 35;

- (id) initWithCoder:(NSCoder *)decoder {
	[super initWithCoder:decoder];
	rows = 0;
	pages = 1;
	pageNum = 1;
	doingPages = NO;  // not needed, used for testing
	return self;
}

- (void) calculatePages {
	rows = [dataSourceWindow numberOfRowsInTableView:nil];  // nil is ok in my case
	pages = (rows / rowsPerPage) + 1; 
	if (pages > 1)
		if ((pages - 1) * rowsPerPage == rows)
			pages = pages - 1;	
}

- (BOOL) knowsPageRange:(NSRangePointer)range {
	[pageDisplay setStringValue:@"Starting Pages"];
	[self calculatePages];
	range->location = 1;
	range->length = pages;
	doingPages = YES;
    return YES;
}

- (NSRect) rectForPage:(int)page {
	pageNum = page;
	[pageDisplay setStringValue:[NSString stringWithFormat:@"Page %i of %i", page, pages]];
	if (page == pages)
		[PrintedTable reloadData];  // otherwise doesn't recall numberOfRowsInTableView
	return [self bounds];	
}

- (void) endDocument {  // not needed, used for testing
	[super endDocument];
	doingPages = NO; 
	pageNum = 1;
	[PrintedTable reloadData];  // otherwise doesn't recall numberOfRowsInTableView
	[pageDisplay setStringValue:@"Finished Doing Pages"];
}

- (int) numberOfRowsInTableView:(NSTableView *)aTableView { 
	if (!doingPages) {
		[self calculatePages];
		pageNum = 1;
		if (pageNum < pages) {
			return rowsPerPage;
		} else {
			return (rows - ((pageNum - 1) * rowsPerPage));
		} 
	} else if (pageNum < pages) {
		return rowsPerPage;
	} else 
		return (rows - ((pageNum - 1) * rowsPerPage));
} 

- (id) tableView:(NSTableView *)aTableView 
		objectValueForTableColumn:(NSTableColumn *)aTableColumn 
			 row:(int)rowIndex { 
	return [dataSourceWindow tableView:aTableView
			 objectValueForTableColumn:aTableColumn
								   row:(((pageNum - 1) * rowsPerPage) + rowIndex)];
}

@end
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
Several comments:

1) CocoaDev.com is a wiki. They don't use HTML formatting for pages. Go read up on how to format your text: TextFormattingRules

2) Didn't want to learn HTML? I don't know a single programmer who doesn't know HTML. You don't have to be a proficient XHTML 1.1 and CSS 3.0 scripter, but at least know basic HTML.

3) Please use the BBCode "code" tag if you're posting code samples on here (or on any forum). And while I'm at it, if you're posting code at CocoaDev, use %%BEGINCODE%% and %%ENDCODE%% around the code.

4) And finally, regarding your topic, I don't know why you'd ever want to print an actual NSTableView. NSTableView is a Mac OS X control that displays columned data. It isn't meant to be printed (although it can be). The printer != the screen. If you want printer functionality, format your data so it is made to fit on a page. Cocoa's documentation covers this. Yes, it may be a pain, but that's life ;)
 

DavidCar

macrumors 6502a
Original poster
Jan 19, 2004
525
0
Several comments:

1) CocoaDev.com is a wiki. They don't use HTML formatting for pages. Go read up on how to format your text: TextFormattingRules

2) Didn't want to learn HTML? I don't know a single programmer who doesn't know HTML. You don't have to be a proficient XHTML 1.1 and CSS 3.0 scripter, but at least know basic HTML.

3) Please use the BBCode "code" tag if you're posting code samples on here (or on any forum). And while I'm at it, if you're posting code at CocoaDev, use %%BEGINCODE%% and %%ENDCODE%% around the code.

4) And finally, regarding your topic, I don't know why you'd ever want to print an actual NSTableView. NSTableView is a Mac OS X control that displays columned data. It isn't meant to be printed (although it can be). The printer != the screen. If you want printer functionality, format your data so it is made to fit on a page. Cocoa's documentation covers this. Yes, it may be a pain, but that's life ;)

Thanks for the suggestions. I've added the BBCode "code" tag, and corrected the initialization. In this case, it was a simple project that wasn't worth the pain of a greater effort.
 

sudhansusingh22

macrumors newbie
Aug 9, 2012
1
0
Not able to prinnt table data

Hi David,
I am still not able to print table view data following your approach. It is still printing only the part of table view to page size. Can you please send me project snippets.
Thanks,
 

DavidCar

macrumors 6502a
Original poster
Jan 19, 2004
525
0
Hi David,
I am still not able to print table view data following your approach. It is still printing only the part of table view to page size. Can you please send me project snippets.
Thanks,

I wouldn't know where to find it now, in a 2007 project. sorry.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.