ASP.NET Core/Razor页面导出到Excel
#网络开发人员 #database #codenewbie #csharp

了解如何从其NuGet package中使用SpreadSheetLight library的SQL-Server数据库表导出数据。

电子表格库是相对未知的,而其他图书馆则像Top 20 NuGet excel Packages中的图书馆相对未知。

了解电子表格可能需要一些时间,但值得花时间。我建议下载他们的帮助文件并通过文档阅读。

将数据导出到Excel

使用现有的现有(您的客户可能在现有项目中要求此)进行剃须页项目,该项目最初创建的EF Core最初用于演示EF Core Shadow属性和查询过滤,并提供一个页面,以显示表中所有记录如果某些设置为软删除,如下所示,在将代码添加到Excel的导出数据之前存在。注意,原始代码中不存在该按钮。

Admin Razor Page

项目中的所有其他页面都使用EF Core,除了此页面。要获取所有记录,以下方法用于返回名为Report的模型的仅读取列表。由于没有理由编辑数据仅读取列表保护数据。

public static async Task<IReadOnlyList<Report>> Reports()
{
    string command =
        """
        SELECT ContactId,
               FirstName,
               LastName,
               LastUser,
               CreatedBy,
               FORMAT(CreatedAt, 'MM/dd/yyyy') AS CreatedAt,
               FORMAT(LastUpdated, 'MM/dd/yyyy') AS LastUpdated,
               IIF(isDeleted = 'TRUE' , 'Y','N') AS Deleted
        FROM dbo.Contact1;
        """;

    await using SqlConnection cn = new(ConnectionString);
    await using SqlCommand cmd = new() { Connection = cn, CommandText = command };

    await cn.OpenAsync();

    var reader = await cmd.ExecuteReaderAsync();

    var list = new List<Report>();

    while (reader.Read())
    {
        list.Add(new Report
        {
            ContactId = reader.GetInt32(0),
            FirstName = reader.GetString(1),
            LastName = reader.GetString(2),
            LastUser = reader.GetString(3),
            CreatedBy = reader.GetString(4),
            CreatedAt = reader.GetString(5),
            LastUpdated = reader.GetString(6),
            Deleted = reader.GetString(7)
        });
    }

    return list.ToImmutableList();

}

上面的方法是从ONPOST事件执行的。 Note StatusMessage是标记为tempdata的页面上的属性,用于显示对话框的创建和填充Excel文件的对话框。

什么可能出了什么问题?更可能这是一个许可问题,而从电子表格下引发的错误将指向开发人员滑倒。

public async Task<PageResult> OnPostExportButton()
{

    Reports = await DataOperations.Reports();

    StatusMessage = ExcelOperations.ExportToExcel(Reports) ? 
        "Report created <strong>successfully</strong>" : 
        "<strong>Failed</strong> to create report";


    return Page();

}

exceloperations.exporttoexcel

获取ReadOnly列表,并将列表转换为数据表,因为这是电子表格希望的期望。要执行此Nuget软件包,FastMember.NetCore被使用,因为这里可能过于杀伤,但是当有成千上万的记录时,FastMember的速度将比家庭烹饪代码更快。

要获得额外的触摸,请迭代dataColumn系列,然后将列名从 firstName 更改为 ,以便在Excel中导入。

有一个数据台,创建一个SLDocument的实例,该实例是与Excel for Excel for for Expellight库进行交互的主要类。

使用the following code的标题行的下一个设置样式。

使用sldocument importdatabable方法,导入datatable

参数

  • 从第一行开始
  • A列开始
  • 导入的数据
  • 是包含标题

注意,如果需要通过更改第一个参数并将最后一个参数设置为false来附加数据。电子表格Light具有以下内容以获取最后的使用行来帮助。

SLDocument.GetWorksheetStatistics().EndRowIndex

接下来,最好不要将Sheep1用于sheetName,因此我们使用 Renameworksheet 将其命名为有意义的名称。

接下来,将每个列宽度设置为自动修复数据。然后设置活动单元格。

创建一个唯一的文件名,然后将数据保存到新的Excel文件中。

完整代码

using System.Data;
using DocumentFormat.OpenXml.Spreadsheet;
using FastMember;
using SpreadsheetLight;
using Color = System.Drawing.Color;

namespace ShadowProperties.Classes;
public class ExcelOperations
{
    /// <summary>
    /// Create a DataTable from <see>
    ///     <cref>{T}</cref>
    /// </see>
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="sender"></param>
    /// <returns></returns>
    public static DataTable ToDataTable<T>(IReadOnlyList<T> sender)
    {
        DataTable table = new();
        using var reader = ObjectReader.Create(sender);
        table.Load(reader);

        return table;
    }

    public static bool ExportToExcel<T>(IReadOnlyList<T> list)
    {
        DataTable table = ToDataTable<T>(list);

        try
        {
            // split column names e.g. FirstName to First Name
            for (int index = 0; index < table.Columns.Count; index++)
            {
                table.Columns[index].ColumnName = table.Columns[index].ColumnName.SplitCamelCase();
            }

            using var document = new SLDocument();

            document.DocumentProperties.Creator = "Karen Payne";
            document.DocumentProperties.Title = "Deleted reports";
            document.DocumentProperties.Category = "ABC Contacts";

            // define first row style
            var headerStyle = HeaderStye(document);

            /*
             * Import DataTable starting at A1, include column headers
             */
            document.ImportDataTable(1, SLConvert.ToColumnIndex("A"), table, true);

            // provides a meaningful sheetname
            document.RenameWorksheet(SLDocument.DefaultFirstSheetName, "Deleted report for contacts");

            // fpr setting style, auto sizing columns
            var columnCount = table.Columns.Count;
            document.SetCellStyle(1, 1, 1, columnCount, headerStyle);

            for (int columnIndex = 1; columnIndex < columnCount + 1; columnIndex++)
            {
                document.AutoFitColumn(columnIndex);
            }

            string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), 
                $"DeletedReport{DateTime.Now:yyyy-MM-dd HH-mm-ss}.xlsx");

            document.SetActiveCell("A2");

            document.SaveAs(fileName);
            return true;
        }
        catch 
        {
            /*
             * Basic reason for failure
             * 1. Developer error
             * 2. User has file open in Excel but here that is not possible because of the file name
             */
            return false;
        }
    }
    /// <summary>
    /// Style for first row in the Excel file
    /// </summary>
    public static SLStyle HeaderStye(SLDocument document)
    {

        SLStyle headerStyle = document.CreateStyle();

        headerStyle.Font.Bold = true;
        headerStyle.Font.FontColor = Color.White;
        headerStyle.Fill.SetPattern(
            PatternValues.LightGray,
            SLThemeColorIndexValues.Accent1Color,
            SLThemeColorIndexValues.Accent5Color);

        return headerStyle;
    }
}

完成的工作表

Finished Excel file

通过对话框提醒用户

Finished dialog

这是使用sweetalert2图书馆切线完成的,并检查标记为tempdata的页面属性。

额外

请参阅项目Shadowproperties中的类文件夹下的Sheethelpers.cs有关电子表格的几种辅助方法。

概括

呈现,如何导入数据以脱颖而出。开发人员可以,如果不需要造型,则可以使用三行代码进行原始导入。

源代码

使用EF Core 7,SQL-Server Database的代码克隆以下GitHub repository

准备跑步

在“ shadowproperties”名为script.sql。

的脚本文件夹下运行脚本

EF核心过滤和阴影属性是新的?

花时间阅读主要的readme file和Microsoft文档。

也可以看看

Learn the basics on immutability已在本文的源代码中使用。该代码以Windows表单呈现,但这并不重要,可以在任何项目类型中使用的内容。

结束

作者积极使用电子表格和GemBox.Spreadsheet