I just went through the same search for a good solution for a custom module I'm almost ready to release.
I have never liked using the DNN print skinobject as it places the print view into a pop-up window. Most users (self included) run with one or more pop-up blockers turned on. I was constantly getting user complaints that clicking the DNN print icon in several DNN sites I manage resulted in a page refresh but no print view. Also, the standard DNN print skin-object does not pass querystring parameters often resulting in a loss of the information filtering the user had set up.
There are a couple of free replacements for the print skin object - DNN Jungle's PagePrint/TemplatePrint Skin comes to mind. It is available at http://dnnjungle.vmasanas.net/Home/tabid/1/Default.aspx and takes care of the querystring problems.
One of the keys to solving the problem is to come up with a css style sheet (contained in module.css) that properly handles the page formatting (as much as possible - page length/breaks is still a real problem) and especially the hiding of controls etc. If you not already familiar with it, look into the use of @Media Print and @Media Screen. Here are a couple of helpful articles on css for printing:
http://meyerweb.com/eric/articles/webrev/200001.html
http://css-discuss.incutio.com/?page=PrintStylesheets
I finally decided to look at how DNN selects the No Skin.ascx skin and No Container.ascx container to create the pop-up print window and modify this basic technique to write a custom printing solution that would display the print view in the current window, properly pass the querystring parameters to my module's print control which would then generate the same data (using nested DataLists) in a print optimized format. Here's a bit of code that makes use of DNN's (undocumented?) capability of specifying a skin in the SkinSrc parameter and the module's container in the ContainerSrc parameter of the querystring:
Function to return url for module's print hyperlink:
Protected Function PrintURL() As String
Return NavigateURL(Me.TabId, "print", GetNavigationParams(True))
End Function
Function to generate querystring parameters including those for print view if Print parameter is true:
Protected Function GetNavigationParams(ByVal Print As Boolean) As String()
Dim params As New ArrayList
Dim result As String()
If RequestID <> -1 Then params.Add("requestid=" & RequestID.ToString)
If PostID <> -1 Then params.Add("postid=" & PostID.ToString)
If AuthorID <> -1 Then params.Add("authorid=" & AuthorID.ToString)
If PageSize <> MyConfiguration.PageSize Then params.Add("pagesize=" & PageSize.ToString)
If CurrentPage <> 1 Then params.Add("currentpage=" & CurrentPage.ToString)
If RequestType <> -1 Then params.Add("type=" & RequestType.ToString)
If Category > 0 Then params.Add("category=" & Category.ToString)
If DateRange < 1 Then params.Add("daterange=" & DateRange.ToString)
If Status > 0 Then params.Add("status=" & Status.ToString)
If OrderBy <> "Order_Date_DESC" Then params.Add("orderby=" & OrderBy)
If Print Then
params.Add("mid=" & ModuleId.ToString)
params.Add("SkinSrc=" & DotNetNuke.Common.Globals.QueryStringEncode((("[G]" & _
Skins.SkinInfo.RootSkin) & "/_default/No Skin")))
params.Add("ContainerSrc=" & DotNetNuke.Common.Globals.QueryStringEncode((("[G]" & _
Skins.SkinInfo.RootContainer) & "/_default/No Container")))
End If
result = CType(params.ToArray(GetType(String)), String())
Return result
End Function
This all seems to work well but I feel that the ultimate and much needed solution is for DNN core to eventually provide built-in pdf creation capabilities, particularly html to pdf. I've also written (for another DNN site) a PDF Generator object that builds upon the open source iTextSharp project to define via xml configuration file(s) a report that is based around a datagrid like section with column data being generated either from a datasource object, sproc name or database SQL command text. One day I'll get around to extending it for other purposes . . .