如何使用C#创建Excel电子表格而不需要在运行代码的计算机上安装Excel?


当前回答

如果您从代码中创建数据表或数据网格视图,则可以使用此简单方法保存所有数据。不建议使用此方法,但它可以100%工作,即使您没有在计算机中安装MS Excel。

try
 {
  SaveFileDialog saveFileDialog1 = new SaveFileDialog();
  saveFileDialog1.Filter = "Excel Documents (*.xls)|*.xls";
  saveFileDialog1.FileName = "Employee Details.xls";
  if (saveFileDialog1.ShowDialog() == DialogResult.OK)
  {
  string fname = saveFileDialog1.FileName;
  StreamWriter wr = new StreamWriter(fname);
  for (int i = 0; i <DataTable.Columns.Count; i++)
  {
  wr.Write(DataTable.Columns[i].ToString().ToUpper() + "\t");
  }
  wr.WriteLine();

  //write rows to excel file
  for (int i = 0; i < (DataTable.Rows.Count); i++)
  {
  for (int j = 0; j < DataTable.Columns.Count; j++)
  {
  if (DataTable.Rows[i][j] != null)
  {
  wr.Write(Convert.ToString(getallData.Rows[i][j]) + "\t");
  }
   else
   {
   wr.Write("\t");
   }
   }
   //go to next line
   wr.WriteLine();
   }
   //close file
   wr.Close();
   }
   }
   catch (Exception)
   {
    MessageBox.Show("Error Create Excel Sheet!");
   }

其他回答

我成功地使用了以下开源项目:

用于OOXML格式的ExcelPackage(Office 2007)XLS格式的NPOI(Office 2003)。NPOI 2.0(Beta版)也支持XLSX。

看看我的博客帖子:

在C中创建Excel电子表格.XLS和.XLSX#

带有Excel表格和动态图表的NPOI

你可能想看看GemBox.Spresheet。

他们有一个免费版本,具有所有功能,但如果符合您的需要,则限制为每张150行,每张工作簿5页。

我还不需要自己使用它,但看起来很有趣。

实际上,您可能想查看C#中可用的互操作类(例如Microsoft.Office.interop.Excel)。您可以说没有OLE(这不是),但互操作类非常容易使用。在这里查看C#文档(Interop for Excel从C#PDF的第1072页开始)。

如果你没有尝试过,你可能会印象深刻。

请注意Microsoft对此的立场:

Microsoft当前不建议也不支持,从任何无人值守、,非交互式客户端应用程序或组件(包括ASP,ASP.NET、DCOM和NT服务),因为Office可能表现出不稳定Office在此环境中运行时的行为和/或死锁。

public class GridViewExportUtil
{
    public static void Export(string fileName, GridView gv)
    {
        HttpContext.Current.Response.Clear();
        HttpContext.Current.Response.AddHeader(
            "content-disposition", string.Format("attachment; filename={0}", fileName));
        HttpContext.Current.Response.ContentType = "application/ms-excel";

        using (StringWriter sw = new StringWriter())
        {
            using (HtmlTextWriter htw = new HtmlTextWriter(sw))
            {
                //  Create a form to contain the grid
                Table table = new Table();

                //  add the header row to the table
                if (gv.HeaderRow != null)
                {
                    GridViewExportUtil.PrepareControlForExport(gv.HeaderRow);
                    table.Rows.Add(gv.HeaderRow);
                }

                //  add each of the data rows to the table
                foreach (GridViewRow row in gv.Rows)
                {
                    GridViewExportUtil.PrepareControlForExport(row);
                    table.Rows.Add(row);
                }

                //  add the footer row to the table
                if (gv.FooterRow != null)
                {
                    GridViewExportUtil.PrepareControlForExport(gv.FooterRow);
                    table.Rows.Add(gv.FooterRow);
                }

                //  render the table into the htmlwriter
                table.RenderControl(htw);

                //  render the htmlwriter into the response
                HttpContext.Current.Response.Write(sw.ToString());
                HttpContext.Current.Response.End();
            }
        }
    }

    /// <summary>
    /// Replace any of the contained controls with literals
    /// </summary>
    /// <param name="control"></param>
    private static void PrepareControlForExport(Control control)
    {
        for (int i = 0; i < control.Controls.Count; i++)
        {
            Control current = control.Controls[i];
            if (current is LinkButton)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as LinkButton).Text));
            }
            else if (current is ImageButton)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as ImageButton).AlternateText));
            }
            else if (current is HyperLink)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as HyperLink).Text));
            }
            else if (current is DropDownList)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as DropDownList).SelectedItem.Text));
            }
            else if (current is CheckBox)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as CheckBox).Checked ? "True" : "False"));
            }

            if (current.HasControls())
            {
                GridViewExportUtil.PrepareControlForExport(current);
            }
        }
    }
}

嗨,这个解决方案是将网格视图导出到excel文件中,这可能会帮助您

您可以在Visual Studio上安装OpenXml nuget包。以下是将数据表导出到excel文件的代码:

Imports DocumentFormat.OpenXml
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Spreadsheet

Public Class ExportExcelClass
    Public Sub New()

    End Sub

    Public Sub ExportDataTable(ByVal table As DataTable, ByVal exportFile As String)
        ' Create a spreadsheet document by supplying the filepath.
        ' By default, AutoSave = true, Editable = true, and Type = xlsx.
        Dim spreadsheetDocument As SpreadsheetDocument = spreadsheetDocument.Create(exportFile, SpreadsheetDocumentType.Workbook)

        ' Add a WorkbookPart to the document.
        Dim workbook As WorkbookPart = spreadsheetDocument.AddWorkbookPart
        workbook.Workbook = New Workbook

        ' Add a WorksheetPart to the WorkbookPart.
        Dim Worksheet As WorksheetPart = workbook.AddNewPart(Of WorksheetPart)()
        Worksheet.Worksheet = New Worksheet(New SheetData())

        ' Add Sheets to the Workbook.
        Dim sheets As Sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild(Of Sheets)(New Sheets())

        Dim data As SheetData = Worksheet.Worksheet.GetFirstChild(Of SheetData)()
        Dim Header As Row = New Row()
        Header.RowIndex = CType(1, UInt32)

        For Each column As DataColumn In table.Columns
            Dim headerCell As Cell = createTextCell(table.Columns.IndexOf(column) + 1, 1, column.ColumnName)
            Header.AppendChild(headerCell)
        Next

        data.AppendChild(Header)

        Dim contentRow As DataRow
        For i As Integer = 0 To table.Rows.Count - 1
            contentRow = table.Rows(i)
            data.AppendChild(createContentRow(contentRow, i + 2))
        Next

    End Sub

    Private Function createTextCell(ByVal columnIndex As Integer, ByVal rowIndex As Integer, ByVal cellValue As Object) As Cell
        Dim cell As Cell = New Cell()
        cell.DataType = CellValues.InlineString

        cell.CellReference = getColumnName(columnIndex) + rowIndex.ToString

        Dim inlineString As InlineString = New InlineString()
        Dim t As Text = New Text()
        t.Text = cellValue.ToString()
        inlineString.AppendChild(t)
        cell.AppendChild(inlineString)
        Return cell
    End Function

    Private Function createContentRow(ByVal dataRow As DataRow, ByVal rowIndex As Integer) As Row
        Dim row As Row = New Row With {
            .rowIndex = CType(rowIndex, UInt32)
        }

        For i As Integer = 0 To dataRow.Table.Columns.Count - 1
            Dim dataCell As Cell = createTextCell(i + 1, rowIndex, dataRow(i))
            row.AppendChild(dataCell)
        Next

        Return row
    End Function

    Private Function getColumnName(ByVal columnIndex As Integer) As String
        Dim dividend As Integer = columnIndex
        Dim columnName As String = String.Empty
        Dim modifier As Integer

        While dividend > 0
            modifier = (dividend - 1) Mod 26
            columnName = Convert.ToChar(65 + modifier).ToString() & columnName
            dividend = CInt(((dividend - modifier) / 26))
        End While

        Return columnName
    End Function
End Class