- MySafeInfo Data API
- Json.NET (Newtonsoft.Json)
- EPPlus
- Response.BinaryWrite
- WebClient.DownloadData
- StreamReader
- Serialization
- Custom Extension Methods
Code-Behind
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Utilities;
namespace Web.excel
{
public partial class _default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// empty
}
public void DownloadFile(byte[] Data, string FileType = "application/csv", string FileName = "data.csv")
{
// headers
Response.BufferOutput = true;
Response.ClearHeaders();
// explicitly append preamble for csv files so excel recognizes utf-8 encoding
if (FileType.ToLower().Contains("csv"))
{
Response.BinaryWrite(System.Text.Encoding.UTF8.GetPreamble());
}
// encoding
Response.ContentEncoding = System.Text.Encoding.UTF8;
// content type
Response.ContentType = FileType;
// content disposition
Response.AddHeader("Content-Disposition", string.Format("attachment; filename=\"{0}\"", FileName));
// data
Response.BinaryWrite(Data);
// end
Response.End();
}
protected void btnDownload_Click(object sender, EventArgs e)
{
// variables
string Result = string.Empty;
string Url = "https://mysafeinfo.com/api/data?list=states&format=json&alias=nm=name,ab=code,cp=capital,yr=year";
List<State> States = new List<State>();
DataTable DT = new DataTable();
byte[] Data = null;
// download json data
using (WebClient client = new WebClient())
{
Result = System.Text.UTF8Encoding.UTF8.GetString(client.DownloadData(Url));
}
// deserialize json data into a List<State>
// Json.NET (Newtonsoft.Json)
// https://www.nuget.org/packages/Newtonsoft.Json
States = Newtonsoft.Json.JsonConvert.DeserializeObject<List<State>>(Result);
// convert List<State> to a DataTable using ToDataTable extension method
DT = States.ToDataTable();
// convert DataTable to byte[] using ToExcel extension method
// EPPlus
// https://www.nuget.org/packages/EPPlus
Data = DT.ToExcel(WorksheetName: "States");
// download excel file
DownloadFile(Data: Data, FileType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", FileName: "states.xlsx");
}
protected void btnUpload_Click(object sender, EventArgs e)
{
// variables
DataTable DT = new DataTable();
List<State> States = new List<State>();
// read excel file in to a StreamReader
using (StreamReader sr = new StreamReader(Server.MapPath("states.xlsx")))
{
// read the underlying stream and convert to a DataTable using ToDataTable extension method
DT = sr.BaseStream.ToDataTable(HasHeader: true);
}
// convert DataTable to a List<State> using ToList extension method
States = DT.ToList<State>().ToList();
// output serialized List<State> so we can see that the excel file was read successfully
lblOutput.Text = States.Serialize();
// show panel
pnlOutput.Visible = true;
}
// state class
public class State
{
public State()
{
Name = string.Empty;
Code = string.Empty;
Capital = string.Empty;
Year = string.Empty;
}
public string Name { get; set; }
public string Code { get; set; }
public string Capital { get; set; }
public string Year { get; set; }
}
}
}
ASPX Page
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="Web.excel._default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<!-- title -->
<title>Excel Demo</title>
<!-- jquery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<!-- bootstrap -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<!-- custom style -->
<style>
body {
margin: 25px !important;
}
.form-group {
width: 800px;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<p>
<asp:Button ID="btnDownload" Text="Download Excel File" CssClass="btn btn-default" Width="200px" OnClick="btnDownload_Click" ClientIDMode="Static" runat="server" />
</p>
<p>
<asp:Button ID="btnUpload" Text="Read Excel File" CssClass="btn btn-default" Width="200px" OnClick="btnUpload_Click" ClientIDMode="Static" runat="server" />
</p>
<asp:PlaceHolder ID="pnlOutput" Visible="false" runat="server">
<p>
<pre><asp:Literal ID="lblOutput" runat="server" /></pre>
</p>
</asp:PlaceHolder>
</div>
</form>
</body>
</html>
Extensions
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Data;
using System.Xml.Serialization;
using System.IO;
using System.Collections.Specialized;
using System.Web;
using System.ComponentModel;
using System.Xml;
using System.Xml.Linq;
using System.Web.UI;
using System.Text.RegularExpressions;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Linq.Expressions;
using System.Net;
using OfficeOpenXml;
namespace Utilities
{
public static class Extensions
{
private static Dictionary<Type, IList<PropertyInfo>> typeDictionary = new Dictionary<Type, IList<PropertyInfo>>();
public static IList<PropertyInfo> GetPropertiesForType<T>()
{
//variables
var type = typeof(T);
//get types
if (!typeDictionary.ContainsKey(typeof(T)))
{
typeDictionary.Add(type, type.GetProperties().ToList());
}
//return
return typeDictionary[type];
}
public static T ToObject<T>(this DataRow row) where T : new()
{
//variables
IList<PropertyInfo> properties = GetPropertiesForType<T>();
//return
return CreateItemFromRow<T>(row, properties);
}
public static IList<T> ToList<T>(this DataTable table) where T : new()
{
//variables
IList<T> result = new List<T>();
//foreach
foreach (DataRow row in table.Rows)
{
result.Add(row.ToObject<T>());
}
//return
return result;
}
private static T CreateItemFromRow<T>(DataRow row, IList<PropertyInfo> properties) where T : new()
{
//variables
T item = new T();
//foreach
foreach (var property in properties)
{
//make sure a column exists in the table with this property name
if (row.Table.Columns.Contains(property.Name))
{
//get the value from the current data row
object value = row[property.Name];
//set property accordingly
if (value != null & value != DBNull.Value)
{
SetProperty<T>(item, property.Name, value);
}
}
}
//return
return item;
}
public static string GetProperty<T>(this T obj, string Property)
{
//reflection
PropertyInfo propertyInfo = obj.GetType().GetProperty(Property, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
object property = null;
//make sure property is valid
if (propertyInfo != null)
{
property = propertyInfo.GetValue(obj, null);
}
//return value
if (property != null)
{
return property.ToString();
}
else
{
return string.Empty;
}
}
public static T SetProperty<T>(this T obj, string Property, object Value)
{
//reflection
PropertyInfo prop = obj.GetType().GetProperty(Property, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
//trim strings
if (Value.GetType() == typeof(string))
{
Value = Value.ToString().Trim();
}
//make sure property is valid
if (prop != null && prop.CanWrite)
{
prop.SetValue(obj, Value, null);
}
//return
return obj;
}
public static string Serialize<T>(this T obj)
{
// Json.NET (Newtonsoft.Json)
// https://www.nuget.org/packages/Newtonsoft.Json
return Newtonsoft.Json.JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.Indented);
}
public static T Deserialize<T>(string data) where T : new()
{
// Json.NET (Newtonsoft.Json)
// https://www.nuget.org/packages/Newtonsoft.Json
return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(data);
}
public static DataTable ToDataTable<T>(this IList<T> data)
{
// variables
PropertyDescriptorCollection Properties = TypeDescriptor.GetProperties(typeof(T));
object[] values = new object[Properties.Count];
DataTable DT = new DataTable();
// columns
foreach (PropertyDescriptor PropertyInfo in Properties)
{
// data column
DataColumn DataColumn = new DataColumn();
// name
DataColumn.ColumnName = PropertyInfo.Name;
// data type
if (PropertyInfo.PropertyType.Name.Contains("Nullable"))
{
DataColumn.DataType = typeof(String);
}
else
{
DataColumn.DataType = PropertyInfo.PropertyType;
}
// add to table
DT.Columns.Add(DataColumn);
}
// rows
foreach (T item in data)
{
for (int i = 0; i < values.Length; i++)
{
values[i] = Properties[i].GetValue(item);
}
DT.Rows.Add(values);
}
// return
return DT;
}
public static bool HasValue(this string Value)
{
return !Value.IsBlank();
}
public static bool IsBlank(this string Value)
{
bool ReturnValue = true;
if (Value != null)
{
ReturnValue = Value.Trim().Length == 0;
}
return ReturnValue;
}
public static byte[] ToExcel(this DataTable DT, string WorksheetName = "Data", bool AutoFormatDates = false)
{
// EPPlus
// https://www.nuget.org/packages/EPPlus
// variables
byte[] Data = null;
ExcelPackage ExcelPackage = new ExcelPackage();
ExcelWorksheet ExcelWorksheet = ExcelPackage.Workbook.Worksheets.Add(WorksheetName.HasValue() ? WorksheetName : "Data");
// load data table with column headings
ExcelWorksheet.Cells["A1"].LoadFromDataTable(DT, true);
// auto-format dates
if (AutoFormatDates)
{
var DateColumns = from DataColumn d in DT.Columns where d.DataType == typeof(DateTime) || d.ColumnName.Contains("Date") select d.Ordinal + 1;
foreach (var Column in DateColumns)
{
ExcelWorksheet.Cells[2, Column, DT.Rows.Count + 1, Column].Style.Numberformat.Format = "mm/dd/yyyy";
}
}
// get data as byte array
Data = ExcelPackage.GetAsByteArray();
// cleanup
ExcelPackage.Dispose();
// return byte array
return Data;
}
public static DataTable ToDataTable(this Stream Data, bool HasHeader = true)
{
// EPPlus
// https://www.nuget.org/packages/EPPlus
// variables
DataTable DT = new DataTable();
var RowStart = HasHeader ? 2 : 1;
using (ExcelPackage ExcelPackage = new ExcelPackage())
{
// load data from stream
ExcelPackage.Load(Data);
// worksheet
ExcelWorksheet ExcelWorksheet = ExcelPackage.Workbook.Worksheets.First();
// create column headings
foreach (var Cell in ExcelWorksheet.Cells[1, 1, 1, ExcelWorksheet.Dimension.End.Column])
{
DT.Columns.Add(HasHeader ? Cell.Text : string.Format("Column {0}", Cell.Start.Column));
}
// copy data from each row to the data table
for (int RowNumber = RowStart; RowNumber <= ExcelWorksheet.Dimension.End.Row; RowNumber++)
{
// variables
ExcelRange Row = ExcelWorksheet.Cells[RowNumber, 1, RowNumber, ExcelWorksheet.Dimension.End.Column];
DataRow DataRow = DT.NewRow();
// copy the data from each cell to the data row
foreach (ExcelRangeBase cell in Row)
{
DataRow[cell.Start.Column - 1] = cell.Text;
}
// add row to data table
DT.Rows.Add(DataRow);
}
}
// return data table
return DT;
}
}
}
Click here to see a fully functional demo.
Matt Pavey is a Microsoft Certified software developer who specializes in ASP.Net, VB.Net, C#, AJAX, LINQ, XML, XSL, Web Services, SQL, jQuery, and more. Follow on Twitter @matthewpavey

0 comments: