在同一本书中创建包含两张纸的 excel 文件 - C#

Create excel file with two sheets in the same book - C#

在我的应用程序中,我有一个 return 一个 excel 文件和一个 sheet 的方法。它工作正常,但现在我需要创建另一个 sheet 并添加它,但我不知道如何做。这是我的代码:

    StringBuilder sb = new StringBuilder();
    string sFileName = "lottery" + Sorteio.Data.Date.ToShortDateString() + ".xls";

    sb.Append("<x:ExcelWorkBook>");
    sb.Append("<x:ExcelWorkSheet>");
    sb.Append("<table style='1px solid black; font-size:12px;'>");

    //many sb.Append(...) with data

    sb.Append("</table>");
    sb.Append("</x:ExcelWorkSheet>");
    sb.Append("<x:ExcelWorkSheet>");
    sb.Append("<table style='1px solid black; font-size:12px;'>");

    //many sb.Append(...) with data

    sb.Append("</table>");
    sb.Append("</x:ExcelWorkSheet>");
    sb.Append("</x:ExcelWorkBook>");

    HttpContext.Response.AddHeader("content-disposition", "attachment; filename=" + sFileName);
    this.Response.ContentType = "application/vnd.ms-excel";
    this.Response.ContentEncoding = System.Text.Encoding.Default;

    System.IO.StringWriter sw = new System.IO.StringWriter();
    System.Web.UI.HtmlTextWriter hw = new HtmlTextWriter(sw);

    byte[] buffer = System.Text.Encoding.Default.GetBytes(sb.ToString());
    return File(buffer, "application/vnd.ms-excel");

在上面的代码中,我创建了包含两个作品sheet的工作簿,每个作品都有自己的 table,但它只为我创建了一个 sheet。不明白为什么它不起作用。

我会使用 OpenXML,代码会是这样的......

// Given a document name, inserts a new worksheet.
public static void InsertWorksheet(string docName)
{
    // Open the document for editing.
    using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(docName, true))
    {
        // Add a blank WorksheetPart.
        WorksheetPart newWorksheetPart = spreadSheet.WorkbookPart.AddNewPart<WorksheetPart>();
        newWorksheetPart.Worksheet = new Worksheet(new SheetData());
        Sheets sheets = spreadSheet.WorkbookPart.Workbook.GetFirstChild<Sheets>();
        string relationshipId = spreadSheet.WorkbookPart.GetIdOfPart(newWorksheetPart);

        // Get a unique ID for the new worksheet.
        uint sheetId = 1;
        if (sheets.Elements<Sheet>().Count() > 0)
        {
            sheetId = sheets.Elements<Sheet>().Select(s => s.SheetId.Value).Max() + 1;
        }

        // Give the new worksheet a name.
        string sheetName = "Sheet" + sheetId;

        // Append the new worksheet and associate it with the workbook.
        Sheet sheet = new Sheet() { Id = relationshipId, SheetId = sheetId, Name = sheetName };
        sheets.Append(sheet);
    }
}

作为@xxmrlnxx 的回答,但适应了问题 - 处理内存中的 "file":

byte[] ExcellInMemory()
{
    using (var m = new MemoryStream())
    {
        SpreadsheetDocument sDoc = SpreadsheetDocument.Create(m, SpreadsheetDocumentType.Workbook);

        WorkbookPart workbookP = sDoc.AddWorkbookPart();
        workbookP.Workbook = new Workbook();

        WorksheetPart workSheetP = workbookP.AddNewPart<WorksheetPart>();
        workSheetP.Worksheet = new Worksheet(new SheetData());

        Sheets sheets = sDoc.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());

        for (UInt32 i = 0; i < 2; i++)
        {
            var sheet = new Sheet()
            {
                Id = sDoc.WorkbookPart.GetIdOfPart(workSheetP),
                SheetId = i,
                Name = "shhet " + i
            };
            sheets.Append(sheet);
        }

        workbookP.Workbook.Save();
        sDoc.Close();

        return m.GetBuffer();
    }

}

像这样使用这个函数:

string sFileName = "lottery" + Sorteio.Data.Date.ToShortDateString() + ".xlsx";
HttpContext.Response.AddHeader("content-disposition", "attachment; filename=" + sFileName);
this.Response.ContentType = "application/vnd.ms-excel";

byte[] buffer = ExcellInMemory();
return File(buffer, "application/vnd.ms-excel");

您可能想要实现自己的 ActionResult,如下所示:Using ASP.NET MVC and the OpenXML API to Stream Excel Files