Printing Datagrid table with many column headers across multiple pages in asp.net
I cannot explain the title in more detail so kindly in the links below. I am using DataGrid (not GridView), in ASP.net using VB code.
This is my current display in my datagrid click here to view picture1 and I want to do it like this clck here to view picture2
My goal is to split my datagrid into multiple datagrid if I have multiple columns. I need to split them up so that I can print it in Google Chrome. Since the print preview in picture 1 using javascript window.print is that it automatically sets my multi-column object to one data file, that way if I have, say, 20 columns of data, the spacing between my columns will be small. and it won't be readable by users. for example click here to view image
if you have any suggestions on how to print my data in a browser, thank you TIA.
<asp:DataGrid Visible ="true" OnItemDataBound="Item_Bound" ID="dgSheet"
runat="server" BackColor="White" BorderColor="black" BorderStyle="None"
BorderWidth="1px" CellSpacing="0" CellPadding="0" Width="100%" PageSize="5"
CssClass="Narrow" ForeColor="Black">
<EditItemStyle BackColor="#999999" />
<FooterStyle BackColor="#2980b9" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#2980b9" ForeColor="White" HorizontalAlign="Center" />
<ItemStyle Font-Size="12px" Width="200" ForeColor="#333333" />
<HeaderStyle Font-Bold="true" Font-Size="12px" Width="200" ForeColor="black" />
<SelectedItemStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
</asp:DataGrid>
My partial code to display my data in a datagrid:
Dim o_Row As DataRow
Dim o_AdmDates As New Collection()
Dim s_LastAdmDate As String = ""
Dim s_AdmDate As String = ""
Dim o_DerivedTable As New DataTable()
With o_DerivedTable
.Columns.Add("TransDate")
.Columns.Add("Medication")
.Columns.Add("Dosage")
.Columns.Add("TransNum")
.Columns.Add("AdministeredDate")
.Columns.Add("newAdmed")
End With
'Sort by administered dates
Dim o_FoundRows As DataRow() = o_Dataset.Tables(0).Select("", "AdministeredDate Desc")
'Extract distinct administered dates
For Each o_Row In o_FoundRows
s_AdmDate = Format(CDate(o_Row.Item("AdministeredDate")), KC_Date_Format2)
If s_LastAdmDate <> s_AdmDate Then
s_LastAdmDate = s_AdmDate
o_AdmDates.Add(s_LastAdmDate)
End If
Next
'Add administred date to derived table
Dim o_Item As String
For Each o_Item In o_AdmDates
o_DerivedTable.Columns.Add(o_Item)
Next
'Loop through the administred date
Dim o_NewRow As DataRow
Dim o_NextRow As DataRow
Dim i_Ctr As Integer
Dim x_isNewRow As Boolean = True
Dim i_MaxRec As Integer
i_MaxRec = o_Dataset.Tables(0).Rows.Count - 1
For i_Ctr = 0 To i_MaxRec
o_Row = o_Dataset.Tables(0).Rows(i_Ctr)
If i_Ctr <> i_MaxRec Then
o_NextRow = o_Dataset.Tables(0).Rows(i_Ctr + 1)
End If
If x_isNewRow Then
o_NewRow = o_DerivedTable.NewRow()
End If
o_NewRow("TransDate") = o_Row("TransDate")
o_NewRow("Medication") = o_Row("Medication")
o_NewRow("Dosage") = o_Row("Dosage")
o_NewRow("TransNum") = o_Row("TransNum")
o_NewRow("AdministeredDate") = Format(CDate(o_Row("AdministeredDate")), KC_Date_Format2)
o_NewRow("newAdmed") = o_Row("newAdmed")
'Fill approriate result date column based on query
For Each o_Item In o_AdmDates
s_AdmDate = Format(CDate(o_Row("AdministeredDate")), KC_Date_Format2)
Dim AdmTim As DateTime = DateTime.Parse(o_Row("AdministeredDate"))
If s_AdmDate = o_Item Then
o_NewRow(s_AdmDate) = AdmTim.ToString("hh:mm tt") + " - " + o_Row("UserID")
End If
Next
If i_Ctr < i_MaxRec _
AndAlso Not o_NextRow Is Nothing _
AndAlso o_Row("TransDate") = o_NextRow("TransDate") _
AndAlso o_Row("Medication") = o_NextRow("Medication") _
AndAlso o_Row("AdministeredDate") = o_NextRow("AdministeredDate") Then
x_isNewRow = False
Else
o_DerivedTable.Rows.Add(o_NewRow)
x_isNewRow = True
End If
Next
dgSheetPrint.DataSource = o_DerivedTable
dgSheetPrint.DataBind()
source to share
First I want to say that you are not printing the datagrid but the html generated by this. Hence, you need to do something on the client side. Since you wrote, you need to break the table and then print. I am attaching a html page from where you can copy the code and modify it to work with your datagrid generated html, you will need to at least change the datagrid id.
Here follows the code
[since you didn't provide the generated html, I made a similar table]
<table id="previousOrderExports" class="chromeTheme">
<tr>
<td class="bold">Export ID</td>
<td class="bold">Request Type</td>
<td class="bold">Timeframe</td>
<td class="bold">Search Filter</td>
<td class="bold">Search Term</td>
<td class="bold">Requested on</td>
<td class="bold">Processed on</td>
<td class="bold">Export Status</td>
<td class="bold">Download</td>
</tr>
<tr>
<td>143306</td>
<td>manual</td>
<td>11/8/14 - 12/8/14</td>
<td>Timespan</td>
<td></td>
<td>12/08/14 03:37:00 AM PST</td>
<td>12/08/14 03:37:08 AM PST</td>
<td>Done</td>
<td><a href="fghhsd.dsfd/sfre/143306">Download</a></td>
</tr>
<tr>
<td>142873</td>
<td>auto</td>
<td>12/7/14 - 12/8/14</td>
<td>Timespan</td>
<td></td>
<td>12/08/14 01:01:10 AM PST</td>
<td>12/08/14 01:03:00 AM PST</td>
<td>Done</td>
<td><a href="fghhsd.dsfd/sfre/142873">Download</a></td>
</tr>
<tr>
<td>142766</td>
<td>auto</td>
<td>12/7/14 - 12/8/14</td>
<td>Timespan</td>
<td></td>
<td>12/07/14 11:01:03 PM PST</td>
<td>12/07/14 11:02:04 PM PST</td>
<td>Done</td>
<td><a href="fghhsd.dsfd/sfre/142766">Download</a></td>
</tr>
<tr>
<td>142752</td>
<td>auto</td>
<td>12/7/14 - 12/8/14</td>
<td>Timespan</td>
<td></td>
<td>12/07/14 10:01:03 PM PST</td>
<td>12/07/14 10:02:05 PM PST</td>
<td>Done</td>
<td><a href="fghhsd.dsfd/sfre/142752">Download</a></td>
</tr>
<tr>
<td>142738</td>
<td>auto</td>
<td>12/7/14 - 12/8/14</td>
<td>Timespan</td>
<td></td>
<td>12/07/14 09:01:03 PM PST</td>
<td>12/07/14 09:02:07 PM PST</td>
<td>Done</td>
<td><a href="fghhsd.dsfd/sfre/142738">Download</a></td>
</tr>
<tr>
<td>142723</td>
<td>auto</td>
<td>12/7/14 - 12/8/14</td>
<td>Timespan</td>
<td></td>
<td>12/07/14 08:01:02 PM PST</td>
<td>12/07/14 08:02:04 PM PST</td>
<td>Done</td>
<td><a href="fghhsd.dsfd/sfre/142723">Download</a></td>
</tr>
<tr>
<td>142709</td>
<td>auto</td>
<td>12/7/14 - 12/8/14</td>
<td>Timespan</td>
<td></td>
<td>12/07/14 07:01:03 PM PST</td>
<td>12/07/14 07:02:04 PM PST</td>
<td>Done</td>
<td><a href="fghhsd.dsfd/sfre/142709">Download</a></td>
</tr>
</table>
<input id="Button1" type="button" value="Print" onclick="print_breakup_table()" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" language="javascript" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
function print_breakup_table()
{
var tableid = "previousOrderExports"; //id of table in this case cliend side id of your datagrid
var fixedcols = 2;// no. of columns 0 index based that will be repeated on every page
var eachpagecols = 3; // no. of columns that will get printed on each page
var colCount = 0;
$('#' + tableid + ' tr:nth-child(1) td').each(function () {
if ($(this).attr('colspan')) {
colCount += +$(this).attr('colspan');
} else {
colCount++;
}
});
colCount--; //get 0 based columncount
var col_left_after_fixed_col = colCount - fixedcols;
var pagerequired = col_left_after_fixed_col / eachpagecols;
if ((col_left_after_fixed_col % eachpagecols)>0) {
pagerequired++;
}
for (var i = 0; i < pagerequired; i++) {
var html = "<table>";
var startcols = fixedcols + (i * eachpagecols);
var endcols = startcols + eachpagecols;
//add fixed cols
$('#' + tableid + ' tr').each(function () {
html += "<tr>";
$(this).children('td').each(function (index, object) {
if (index <= fixedcols) {
html += "<td>" + $(this).html() + "</td>";
} else {
if (index <= endcols && index >= startcols) {
html += "<td>" + $(this).html() + "</td>";
}
}
});
html += "</tr>";
});
html += "</table>";
myWindow = window.open('', '', 'width=800,height=600');
myWindow.document.write(html);
myWindow.document.close();
myWindow.focus();
myWindow.print();
}
}
</script>
source to share
You will need to specifically program the view that has tables the way you want. Then you can add a button to print it
<a class="miniprint" href="/url/to/print/view">Print</a>
JavaScript:
$(document).on('click', '.miniprint', function (event) {
event.preventDefault();
var self = $(this);
var url = self.attr("href");
$("#printjob").remove();
$('<iframe id="printjob" src="' + url + '">')
.load(function () {
this.focus();
document.getElementById("printjob").contentWindow.print();
})
.css({ position: "absolute", left: "-10000px", top: "0px" })
.appendTo(document.body);
});
Also, I suggest telling Google Chrome to print it in landscape orientation using
@media print {
@page {size: landscape}
}
source to share