Hola.
Para tratar la exportación de los datos del
jqGrid a Excel, vamos a partir del proyecto que generamos en el anterior
tutorial sobre jqGrid.
En el proyecto anterior ya habíamos creado dentro del webservice
un código que generaba los datos suministrados por nuestra supuesta Base de
datos, así pues lo que haremos a continuación es mover ese código del web
service a la clase que hemos creado y hacer que el WebService solicite esta
información a dicha clase y que continúe funcionando como hasta
ahora.
Así pues moveremos del WebService el siguiente
bloque de código:
List<Pago> data = new List<Pago>();
Random rnd
= new Random();
for
(int n = 0; n <
30; n++)
{
int num_days
= rnd.Next(-365, -30);
DateTime
fecha = DateTime.Today.AddDays(num_days);
decimal
importe = Math.Round(Convert.ToDecimal((rnd.NextDouble() * 1000)),
2);
decimal tasa
= Math.Round(Convert.ToDecimal((rnd.NextDouble() * 100)),
2);
decimal total
= Math.Round((importe + tasa), 2);
data.Add(new Pago()
{
ID = n
+ 1,
FechaPago = fecha,
Concepto = "JOHN DOE " + (n + 1).ToString(),
Importe
= importe,
Tasas =
tasa,
Total =
total,
Notas = "Nota
" + (n + 1).ToString()
});
}
|
Y crearemos en la clase “PagosController” el
siguiente método con el código movido:
public
static List<Pago>
GetListaPagos()
{
List<Pago> data = new List<Pago>();
Random rnd
= new Random();
for
(int n = 0; n <
30; n++)
{
int num_days
= rnd.Next(-365, -30);
DateTime
fecha = DateTime.Today.AddDays(num_days);
decimal
importe = Math.Round(Convert.ToDecimal((rnd.NextDouble() * 1000)),
2);
decimal tasa
= Math.Round(Convert.ToDecimal((rnd.NextDouble() * 100)),
2);
decimal total
= Math.Round((importe + tasa), 2);
data.Add(new
Pago()
{
ID = n +
1,
FechaPago =
fecha,
Concepto = "JOHN DOE " + (n + 1).ToString(),
Importe
= importe,
Tasas =
tasa,
Total =
total,
Notas = "Nota
" + (n + 1).ToString()
});
}
return
data;
}
|
Por último haremos que el webservice llame a
este método para solicitar la información
List<Pago> data =
Controller.PagosController.GetListaPagos();
|
De esta forma el WebService se comporta igual y
ahora podemos llamar a GetListaPagos
desde otros puntos de la solución.
En este punto, antes de continuar, podríais
ejecutar la solución para aseguraros que la página del grid continua funcionando
como hasta ahora.
Ahora vamos a hacer es generar una Pagina aspx,
la cual va a recibir las distintas peticiones de exportación y se encargará de
recoger los datos y exportarlos a Excel.
Así pues crearemos una nueva página a la que
llamaremos “Export2Excel.aspx”.
La idea en esta página es llamar el método del
controlador que nos proporciona los datos a exportar. Convertir la lista de
Pagos en un DataTable y retornar el data table exportado a
Excel.
Para realizar estas acciones, lo primero que
vamos a generar es un conjunto de métodos que nos permitirán convertir nuestras
listas genéricas en Datatables. Creamos el siguiente código en nuestra
página:
public
static DataTable
ConvertTo<T>(IList<T> list)
{
DataTable
table = CreateTable<T>();
Type
entityType = typeof(T);
PropertyDescriptorCollection
properties = TypeDescriptor.GetProperties(entityType);
foreach (T
item in
list)
{
DataRow
row = table.NewRow();
foreach
(PropertyDescriptor prop in properties)
{
row[prop.Name] =
prop.GetValue(item) ?? DBNull.Value;
}
table.Rows.Add(row);
}
return
table;
}
public
static DataTable
CreateTable<T>()
{
Type entityType = typeof(T);
DataTable
table = new
DataTable(entityType.Name);
PropertyDescriptorCollection
properties = TypeDescriptor.GetProperties(entityType);
foreach
(PropertyDescriptor prop in properties)
{
// HERE IS WHERE THE ERROR IS THROWN
FOR NULLABLE TYPES
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ??
prop.PropertyType);
}
return
table;
}
|
Con los métodos creados, vamos a proceder a
crear una función que se encargue de generar la respuesta en formato Excel a
partir de un Datatable. Así pues, creamos el siguiente
código:
public static void ExportToExcel(string fileName, DataTable
dt)
{
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader(
"content-disposition", string.Format("attachment;
filename={0}",
fileName));
HttpContext.Current.Response.ContentType = "application/ms-excel";
string tab =
"";
foreach
(DataColumn dc
in
dt.Columns)
{
HttpContext.Current.Response.Write(tab +
dc.ColumnName);
tab = "\t";
}
HttpContext.Current.Response.Write("\n");
int
i;
foreach
(DataRow dr
in
dt.Rows)
{
tab = "";
for (i = 0; i
< dt.Columns.Count; i++)
{
HttpContext.Current.Response.Write(tab +
dr[i].ToString());
tab = "\t";
}
HttpContext.Current.Response.Write("\n");
}
HttpContext.Current.Response.End();
}
|
Ya tenemos todos los elementos que necesitamos
para la exportación.
Solo nos falta unificar todos estos puntos en
el Page_Load de la página:
protected
void
Page_Load(object
sender, EventArgs
e)
{
List<Pago> data =
Controller.PagosController.GetListaPagos();
DataTable dt =
ConvertTo(data);
ExportToExcel("ListaPagos.xls",
dt);
}
|
Ya tenemos nuestra página de exportación a
Excel lista para ser invocada.
Vamos ahora a enlazar nuestro jqGrid con esta
página.
Para ello vamos a agregar al jqGrid un botón
que al ser pulsado invocara nuestra página.
Asi el código de nuestro jqGrid quedará de la
siguiente forma.
jQuery(document).ready(function ()
{
$("#contactsList").jqGrid({
url: '/WsDataProvider.asmx/GetGridDataOrder',
datatype: 'json',
mtype: 'POST',
ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
serializeGridData: function (postData) {
return
JSON.stringify(postData);
},
jsonReader: { repeatitems: false, root: "d.rows", page: "d.page", total: "d.total", records:
"d.records"
},
colModel: [
{ name: 'ID', label: 'ID', key: true, width: 60, sortable:
true, align:
"center", hidden:
false
},
{ name: 'FechaPago', label:
'Fecha', width:
80, sortable: true,
hidden: false,
formatter: 'date',
formatoptions: { srcformat: 'm/d/Y
h:i:s', newformat: 'd-m-Y'}
},
{ name: 'Concepto', label: 'Concepto', width: 180,
sortable: true,
hidden: false
},
{ name: 'Importe', label: 'Importe', width: 180,
sortable: true,
align: "center",
hidden: false,
formatter:currencyFmatter },
{ name: 'Tasas', label: 'Tasa', key: true, width: 60, sortable:
true, align:
"center", hidden:
false, formatter:
currencyFmatter },
{ name: 'Total', label: 'Total', width: 80, sortable:
true, align:
"center", hidden:
false, formatter:
currencyFmatter },
{ name: 'Notas', label: 'Notas', width: 180, sortable:
false, hidden:
false
}
],
rowNum: 10,
rowList: [10, 20, 30],
pager: "#gridpager",
viewrecords: true,
gridview: true,
rownumbers: true,
height: 420, width: 980,
caption: 'Lista de
Pagos'
}).jqGrid('navGrid', '#gridpager', {
edit: true, add: true, del: false, search: true
}).jqGrid('navButtonAdd', '#gridpager',
{
caption: '<span
class="ui-pg-button-text">Export</span>',
buttonicon: "ui-icon-extlink",
title: "Export To Excel",
onClickButton: function () {
window.location =
'Export2Excel.aspx';
}
});
});
|
He
marcado en gris el código que se encarga de generar el botón de
exportación.
Pues ya solo nos falta
probarlo.
Ya tenemos nuestro jqGrid con exportación de datos a
Excel.
Como siempre, teneis a vuestra disposición el proyecto para que lo
estudieis
Espero que os sea de ayuda, a partir de aquí
podéis sofisticar el sistema como queráis.
Saludos.-