Skip to content

Instantly share code, notes, and snippets.

@eternalharvest
Last active September 7, 2018 18:30
Show Gist options
  • Save eternalharvest/0a1d63ccead0e571e4c869200484af1e to your computer and use it in GitHub Desktop.
Save eternalharvest/0a1d63ccead0e571e4c869200484af1e to your computer and use it in GitHub Desktop.
/**
*
* Simple Excel Template Engine v0.8
* Copyright (c)2018 Takuya Sawada <takuya@tuntunkun.com>
*
* This software is released under the MIT License.
* http://opensource.org/licenses/mit-license.php
*
*/
using System;
using System.IO;
using System.Data;
using System.Data.Common;
using System.Collections.Generic;
using System.Reflection;
using ClosedXML.Excel;
public class ExcelTemplate : IDisposable
{
protected string _srcfile;
protected string _dstfile;
protected byte[] _data;
protected XLWorkbook _workbook = null;
public XLWorkbook workbook
{
get
{
return _workbook;
}
}
public string srcfile
{
get
{
return _srcfile;
}
}
public string dstfile
{
get
{
return _dstfile;
}
}
public ExcelTemplate(byte[] data)
{
_data = data;
}
public ExcelTemplate(string srcfile)
{
_srcfile = srcfile;
}
public void render(string dstfile, Dictionary<string, object> data)
{
_reset();
foreach (IXLNamedRange nr in _workbook.NamedRanges)
{
if (data.ContainsKey(nr.Name))
{
_workbook.Cell(nr.Name).Value = data[nr.Name];
}
}
foreach (IXLWorksheet ws in _workbook.Worksheets)
{
foreach (IXLTable table in ws.Tables)
{
if (data.ContainsKey(table.Name))
{
if (data[table.Name] is IEnumerable<object>)
{
IEnumerator<object> iter = ((IEnumerable<object>)data[table.Name]).GetEnumerator();
Dictionary<string, PropertyInfo> props = new Dictionary<string, PropertyInfo>();
int index;
if (iter.MoveNext())
{
foreach (PropertyInfo prop in iter.Current.GetType().GetProperties())
{
props.Add(prop.Name, prop);
}
}
index = 1;
foreach (object row in (IEnumerable<object>)data[table.Name])
{
if (index > table.DataRange.RowCount())
{
table.DataRange.InsertRowsBelow(1);
table.DataRange.Row(index - 1).CopyTo(table.DataRange.Row(index));
}
index++;
}
index = 1;
foreach (object row in (IEnumerable<object>)data[table.Name])
{
foreach (IXLTableField field in table.Fields)
{
if (row is Dictionary<string, object>)
{
Dictionary<string, object> dict = (Dictionary<string, object>)row;
if (dict.ContainsKey(field.Name))
{
table.DataRange.Row(index).Field(field.Name).Value = dict[field.Name];
continue;
}
}
if (props.ContainsKey(field.Name))
{
table.DataRange.Row(index).Field(field.Name).Value = props[field.Name].GetValue(row);
}
}
index++;
}
}
if (data[table.Name] is DbDataReader)
{
DbDataReader reader = (DbDataReader)data[table.Name];
List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
HashSet<string> cols = new HashSet<string>();
int index;
if (reader.HasRows)
{
foreach (DataRow row in reader.GetSchemaTable().Rows)
{
cols.Add((string)row["ColumnName"]);
}
index = 1;
while (reader.Read())
{
Dictionary<string, object> dict = new Dictionary<string, object>();
if (index > table.DataRange.RowCount())
{
table.DataRange.InsertRowsBelow(1);
table.DataRange.Row(index - 1).CopyTo(table.DataRange.Row(index));
}
foreach (IXLTableField field in table.Fields)
{
if (cols.Contains(field.Name))
{
dict.Add(field.Name, reader[field.Name]);
}
}
rows.Add(dict);
index++;
}
index = 1;
foreach (Dictionary<string, object> row in rows)
{
foreach (string key in row.Keys)
{
table.DataRange.Row(index).Field(key).Value = row[key];
}
index++;
}
}
}
}
}
}
_workbook.SaveAs(dstfile);
}
public void render(Dictionary<string, object> data)
{
String dstfile = Path.ChangeExtension(Path.GetTempFileName(), "xlsx");
render(dstfile, data);
_dstfile = dstfile;
}
protected void _reset()
{
Dispose();
if (_data != null)
{
MemoryStream stream = new MemoryStream();
stream.Write(_data, 0, _data.Length);
_workbook = new XLWorkbook(stream);
}
else
{
_workbook = new XLWorkbook(_srcfile);
}
}
public void Dispose()
{
if (_workbook != null)
{
_workbook.Dispose();
_workbook = null;
}
if (_dstfile != null)
{
if (File.Exists(_dstfile))
{
File.Delete(_dstfile);
}
_dstfile = null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment