Reputation: 1368
I have a stored procedure that returns extra columns. I don't have control of the stored procedure. I would like to use the following form to generate my worksheet:
ws.Cells.LoadFromDataTable(dt, true, OfficeOpenXml.Table.TableStyles.Light8)
How can I output just the columns I want?
I tried to figure out a Linq query but the problem is that the column names are inaccessible so I can't specify which columns I would like.
SqlConnection cx = new SqlConnection(util.GetConnectionString());
SqlCommand cmd = new SqlCommand("StoredRept", cx);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter ta = new SqlDataAdapter();
ta.SelectCommand = cmd;
DataTable dt = new DataTable();
ta.Fill(dt);
FileInfo newFile = new FileInfo("c:\temp");
ExcelPackage epp = new ExcelPackage(newFile);
var ws = epp.Workbook.Worksheets.Add("WS");
// here is where I would like to copy certain columns off into another data table but I haven't been able to figure out how
ws.Cells.LoadFromDataTable(dt, true, OfficeOpenXml.Table.TableStyles.Light8);
Any help would be greatly appreciated.
Upvotes: 1
Views: 79
Reputation: 2046
Can you load your spreadsheet with IEnumerable<T>
instead of DataTable
? If so:
var someColumns = dt
.AsEnumerable()
.Select(row => new
{
When = row.Field<DateTime>("When"),
What = row.Field<string>("What"),
HowMany = row.Field<int>("ColumnNameInDatabase"),
});
If you need DataTable
, you can convert IEnumerable
to it via any method, like this or this.
Frankly, I answered your problem, but IMO you've a greater problem at hand, which is using those antiquated DataTable
objects instead of IEnumerable<T>
. If you consider, for example, Dapper
library, you could do this:
util.GetConnectionString()
.Query("StoredRept", commandType: CommandType.StoredProcedure) // Extension method from Dapper
.Select(dyn => new
{
When = (DateTime)dyn.When,
What = (string)dyn.What,
HowMany = (int)dyn.ColumnNameInDatabase
})
I see you're using EPPlus
library for Excel manipulation. It can load IEnumerable<T>
data, you are not restricted to DataTable
.
Upvotes: 2
Reputation: 40537
If removing some columns from the table is the only problem, that is easy to resolve. Try something like this:
var dt = new DataTable();
dt.Columns.Add("First", typeof(string));
dt.Columns.Add("Second", typeof(string));
dt.Columns.Add("Third", typeof(string));
dt.Columns.Add("Fourth", typeof(string));
dt.Columns.Add("Fifth", typeof(string));
for (var i = 1; i < 6; i++)
{
dt.Rows.Add($"First {i}", $"Second {i}", $"Third {i}",$"Fourth {i}",$"Fifth {i}");
}
//dt.Dump();//If you have linqpad this is handy to dump table to output
//REMOVE THE COLUMNS.
dt.Columns.RemoveAt(1);
dt.Columns.RemoveAt(2);
//dt.Dump();//again in linqpad this dumps table with remaining 3 columns
You can use following method to find column by name and remove it:
var col=dt.Columns["Second"];
dt.Columns.Remove(col);
Here is linq query to get list with desired columns.
var lq = (from DataRow r in dt.Rows
select new { First = r[0], Second=r[1], Third=r["Fifth"]}
).ToList();
lq.Dump();
Note how you can use both column index or name to get value from row object.
Upvotes: 2