使用DataTable和Linq导出到Excel中缺less一些数据

我正在导出单个XL文件中的三个工作表,但我缺less第二个DataTableEducation Details表)和第三个DataTableEmployeement Details表)中的一些用户数据。

Education Details表是有些用户不在,但用户正在显示的“ Employeement Details表。 用户电子邮件ID是那里所有三个数据库表。

  DataSe ds = new DataSet(); DataTable dt = new DataTable("Registration Details"); DataTable dt1 = new DataTable("Education Details"); DataTable dt2 = new DataTable("Employeement Details"); dt = bl.Get_Registrationdetailsbydate(bo); gv_Regdetails.DataSource = dt; gv_Regdetails.DataBind(); dt1 = bl.Get_Registrationdetailsbydate1(bo); dt2 = bl.Get_Registrationdetailsbydate2(bo); DataTable filteredEducation = dt1.AsEnumerable() .Where(x => dt.AsEnumerable() .Any(z => z.Field<string>("Email").Trim() == x.Field<string>("Email").Trim())) .CopyToDataTable(); DataTable filteredEmployee = dt2.AsEnumerable() .Where(x => dt.AsEnumerable() .Any(z => z.Field<string>("Email").Trim() == x.Field<string>("Email").Trim())) .CopyToDataTable(); dt.TableName = "Registration Details"; filteredEducation.TableName = "Education Details"; filteredEmployee.TableName = "Employeement Details"; ds.Tables.Add(dt); ds.Tables.Add(filteredEducation); ds.Tables.Add(filteredEmployee); ExcelHelper.ToExcel(ds, "DangoteUsers.xls", Page.Response); 

我做了基于第一个DataTable用户Email ,然后根据第一个DataTable Email ID填充第二个DataTable详细用户。 与Employment Details相同。 第一个DataTable和第二个DataTable 。 我也没有返回DataTable

我参考这个例子

我认为你的string比较linq查询是一个问题..你的电子邮件地址可能会有不同的情况下,可能导致这个问题。 尝试下面的代码

 DataTable filteredEducation = dt1.AsEnumerable() .Where(x => dt.AsEnumerable() .Any(z => z.Field<string>("Email").Trim().Equals(x.Field<string>("Email").Trim(),StringComparison.CurrentCultureIgnoreCase))) .CopyToDataTable(); DataTable filteredEmployee = dt2.AsEnumerable() .Where(x => dt.AsEnumerable() .Any(z => z.Field<string>("Email").Trim().Equals(x.Field<string>("Email").Trim(),StringComparison.CurrentCultureIgnoreCase))) .CopyToDataTable(); 

这个问题来自于文章中从DataSet到Excel转换的解决scheme。 使用这个自制的转换不是一个好主意。 使用Jet/ACE engineMicrosoft Office Interop 。 至less他们保证,他们没有这样的bug,将来可能会变得更多。 更好地使用已经被社区高度接受的东西。 在这里,我写了一个如何与Interop一起做的方法。

首先你需要做的是添加对Microsoft.Office.Interop.Excel的引用。 这里是如何做到这一点,从MSDN文章

添加Excel程序集作为对项目的引用:右键单击项目,select添加引用。

单击添加引用对话框的COM选项卡,然后findMicrosoft Excel 11对象库。

双击Microsoft Excel 11对象库,然后按确定。

显然,如果你有更大版本的Excel 11使用它。

这里是代码,有它的工作stream程的评论/地区。 你应该使用using Excel = Microsoft.Office.Interop.Excel; 作为参考

  public void ExcelBtn_Click(object sender, EventArgs e) { DataSet dst = PrepareData(); byte[] bytes = ExportDataSetToExcel(dst); Response.ClearContent(); Response.ContentType = "application/msoffice"; Response.AddHeader("Content-Disposition", @"attachment; filename=""ExportedExcel.xlsx"" "); Response.BinaryWrite(bytes); Response.End(); } public static DataSet PrepareData() { DataTable badBoysDst = new DataTable("BadBoys"); badBoysDst.Columns.Add("Nr"); badBoysDst.Columns.Add("Name"); badBoysDst.Rows.Add(1, "Me"); badBoysDst.Rows.Add(2, "You"); badBoysDst.Rows.Add(3, "Pepe"); badBoysDst.Rows.Add(4, "Roni"); //Create a Department Table DataTable goodBoysDst = new DataTable("GoodBoys"); goodBoysDst.Columns.Add("Nr"); goodBoysDst.Columns.Add("Name"); goodBoysDst.Rows.Add("1", "Not me"); goodBoysDst.Rows.Add("2", "Not you"); goodBoysDst.Rows.Add("3", "Quattro"); goodBoysDst.Rows.Add("4", "Stagioni"); DataTable goodBoysDst2 = new DataTable("GoodBoys2"); goodBoysDst2.Columns.Add("Nr"); goodBoysDst2.Columns.Add("Name"); goodBoysDst2.Rows.Add("1", "Not me"); goodBoysDst2.Rows.Add("2", "Not you"); goodBoysDst2.Rows.Add("3", "Quattro"); goodBoysDst2.Rows.Add("4", "Stagioni"); DataTable goodBoysDst3 = new DataTable("GoodBoys3"); goodBoysDst3.Columns.Add("Nr"); goodBoysDst3.Columns.Add("Name"); goodBoysDst3.Rows.Add("1", "Not me"); goodBoysDst3.Rows.Add("2", "Not you"); goodBoysDst3.Rows.Add("3", "Quattro"); goodBoysDst3.Rows.Add("4", "Stagioni"); //Create a DataSet with the existing DataTables DataSet dst = new DataSet("SchoolBoys"); dst.Tables.Add(badBoysDst); dst.Tables.Add(goodBoysDst); dst.Tables.Add(goodBoysDst2); dst.Tables.Add(goodBoysDst3); return dst; } public static byte[] ExportDataSetToExcel(DataSet dst) { #region Create The Excel Excel.Application excelApp = null; Excel.Workbook excelWorkBook = null; try { excelApp = new Excel.Application(); if (excelApp == null) throw new Exception("You can throw custom exception here too"); excelWorkBook = excelApp.Workbooks.Add(); int sheetNr = 1; foreach (DataTable table in dst.Tables) { Excel.Worksheet excelWorkSheet = null; //Add a new worksheet or reuse first 3 sheets of workbook with the Datatable name if (sheetNr <= excelWorkBook.Sheets.Count) { excelWorkSheet = excelWorkBook.Sheets.get_Item(sheetNr); } else { excelWorkSheet = excelWorkBook.Sheets.Add(After: excelWorkBook.Sheets[excelWorkBook.Sheets.Count]); } excelWorkSheet.Name = table.TableName; for (int i = 1; i < table.Columns.Count + 1; i++) { excelWorkSheet.Cells[1, i] = table.Columns[i - 1].ColumnName; } for (int j = 0; j < table.Rows.Count; j++) { for (int k = 0; k < table.Columns.Count; k++) { excelWorkSheet.Cells[j + 2, k + 1] = table.Rows[j].ItemArray[k].ToString(); } } sheetNr += 1; } //make first sheet active excelApp.ActiveWorkbook.Sheets[1].Select(); excelWorkBook.SaveAs(@"c:\temp\DataSetToExcel.xlsx"); } finally { excelWorkBook.Close(); excelApp.Quit(); //you should call GC here because there is memory problem with Interop GC.Collect(); GC.WaitForPendingFinalizers(); } #endregion #region Take byte[] of the excel byte[] result = null; using (FileStream fs = new FileStream(@"c:\temp\DataSetToExcel.xlsx", FileMode.Open, FileAccess.Read)) { BinaryReader reader = new BinaryReader(fs); result = reader.ReadBytes((int)fs.Length); } #endregion #region Delete the excel from the server File.Delete(@"c:\temp\DataSetToExcel.xlsx"); #endregion return result; } } 

所以试着使用社区已经build立的东西。这是非常充分的例子如何与Interop做到这一点。 我个人更喜欢使用ACE / JET引擎,因为在Interop中没有内存泄漏问题(因为我们在代码中调用GC)。 用ACE / JET引擎创build新的表单有点困难。

我通过手动导出完成了相同的导出问题。 首先,我需要准备一个responce http响应正确,比添加表的所有标题(与rowsapncolspan属性),然后填充数据:

 //this fun is called after click on export button for example public void Export(string fileName, GridView gv) { try { HttpContext.Current.Response.Clear(); HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}", String.Format("{0}.xls", fileName))); HttpContext.Current.Response.AddHeader("Content-Transfer-Encoding", "utf-8"); HttpContext.Current.Response.Buffer = true; HttpContext.Current.Response.ContentType = "application/vnd.ms-excel"; HttpContext.Current.Response.Write(@"<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN"">"); HttpContext.Current.Response.Charset = "utf-8";//"windows-1251";// HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8"); using (StringWriter sw = new StringWriter()) { using (HtmlTextWriter htw = new HtmlTextWriter(sw)) { // Create a table to contain the grid Table table = new Table(); table.Width = Unit.Percentage(100); // include the gridline settings table.GridLines = gv.GridLines; //header TableRow r = new TableRow(); TableCell cell = new TableCell() { ColumnSpan = 18, Text = fileName, BackColor = Color.LightGray, HorizontalAlign = HorizontalAlign.Center }; cell.Font.Size = new FontUnit(14); r.Cells.Add(cell); table.Rows.Add(r); GridViewRow row; int rowSpan = 0; //second row row = CreateSecondHeaderRow(); table.Rows.AddAt(1, row); //first row row = CreateFirstHeaderRow(row, rowSpan); table.Rows.AddAt(1, row); // add each of the data rows to the table for (int j = 0; j < gv.Rows.Count; j++) { //Set the default color gv.Rows[j].BackColor = System.Drawing.Color.White; for (int i = 0; i < gv.Rows[j].Cells.Count; i++) { gv.Rows[j].Cells[i].BackColor = System.Drawing.Color.White; gv.Rows[j].Cells[i].Width = gv.Columns[i].ItemStyle.Width; gv.Rows[j].Cells[i].Font.Size = gv.Columns[i].ItemStyle.Font.Size; gv.Rows[j].Cells[i].Font.Bold = gv.Columns[i].ItemStyle.Font.Bold; gv.Rows[j].Cells[i].Font.Italic = gv.Columns[i].ItemStyle.Font.Italic; //aligh if (i == 0) { gv.Rows[j].Cells[i].Style["text-align"] = "center"; } else { gv.Rows[j].Cells[i].Style["text-align"] = "right"; } //for alternate if (j % 2 != 1) gv.Rows[j].Cells[i].BackColor = Color.LightSteelBlue; } table.Rows.Add(gv.Rows[j]); } table.RenderControl(htw); // render the htmlwriter into the response HttpContext.Current.Response.Write(sw); HttpContext.Current.Response.Flush(); HttpContext.Current.Response.End(); } } } catch (Exception ex) { this._hasError = true; ShowError(ex); } } private TableHeaderCell CreateHeaderCell(string text = null, int rowSpan = 0, int columnSpan = 0, Color backColor = default(Color), Color foreColor = default(Color)) { if (object.Equals(backColor, default(Color))) backColor = Color.LightGray; if (object.Equals(foreColor, default(Color))) foreColor = Color.Black; return new TableHeaderCell { RowSpan = rowSpan, ColumnSpan = columnSpan, Text = text, BackColor = backColor }; } private GridViewRow CreateFirstHeaderRow(GridViewRow row, int rowSpan) { row = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Insert); TableHeaderCell cell = CreateHeaderCell("Surplus %"); row.Controls.Add(cell); cell = CreateHeaderCell("The date", columnSpan: 2); row.Controls.Add(cell); if (this.WithQuantity) { cell = CreateHeaderCell("Total Quantity", 2 + rowSpan, backColor: Color.Yellow); row.Controls.Add(cell); } cell = CreateHeaderCell("Total Amount", 2 + rowSpan); row.Controls.Add(cell); cell = CreateHeaderCell("Has elapsed periods from start", columnSpan: (this.WithQuantity ? (SurplusUtil.TheColumnsNumbers * 2) : SurplusUtil.TheColumnsNumbers)); row.Controls.Add(cell); if (this.WithQuantity) { cell = CreateHeaderCell("Quantity <br style='mso-data-placement:same-cell;' /> surplus", 2 + rowSpan, backColor: Color.Yellow); row.Controls.Add(cell); } cell = CreateHeaderCell("Principal <br style='mso-data-placement:same-cell;' /> surplus", 2 + rowSpan); row.Controls.Add(cell); return row; } private GridViewRow CreateSecondHeaderRow() { GridViewRow row = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Insert); TableHeaderCell cell = CreateHeaderCell("Period number", rowSpan: ((this.WithQuantity) ? 2 : 0)); row.Controls.Add(cell); cell = CreateHeaderCell("from", rowSpan: ((this.WithQuantity) ? 2 : 0)); row.Controls.Add(cell); cell = CreateHeaderCell("to", rowSpan: ((this.WithQuantity) ? 2 : 0)); row.Controls.Add(cell); for (int i = 0; i < SurplusUtil.TheColumnsNumbers; i++) { cell = CreateHeaderCell(i.ToString(), columnSpan: ((this.WithQuantity) ? 2 : 0), backColor: System.Drawing.Color.FromArgb(198, 239, 206), foreColor: System.Drawing.Color.FromArgb(0, 97, 0)); row.Controls.Add(cell); } return row; }