使用DataTable和Linq导出到Excel中缺少某些数据

时间:2016-01-27 08:12:18

标签: c# asp.net excel linq datatable

我在单个XL文件中导出三个工作表,但我在第二个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 DataTable个ID填充第二个Email详细信息用户。与Employment Details相同。第一个DataTable和第二个DataTable中的问题。我也没有退回DataTable

我引用this example

3 个答案:

答案 0 :(得分:3)

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

首先,您需要添加对Microsoft.Office.Interop.Excel的引用。以下是如何执行此操作,取自msdn article

  

添加Excel程序集作为项目的引用:右键单击   在项目中,选择Add Reference。

     

单击“添加引用”对话框的“COM”选项卡,然后找到Microsoft   Excel 11对象库。

     

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

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

这是代码,有评论/区域及其工作流程。您应该使用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;
    }

}

所以尝试使用已经由社区建立的东西。这是如何使用Interop完成的完整示例。 我个人更喜欢使用ACE / JET引擎,因为Interop中没有内存泄漏问题(因为我们在代码中调用了GC)。使用ACE / JET引擎创建新工作表有点困难。

答案 1 :(得分:1)

我认为您在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();

答案 2 :(得分:0)

我通过手动导出完成了相同的导出问题。首先,我需要正确准备响应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;
}