[硬核] Bootstrap Blazor Table 综合演示例子

知识点:

1.导入导出
2.分页功能
3.增删改查
4.批量删除
5.批量编辑(审核)
6.列排序与列搜索
7.顶部搜索实现所有列搜索
8.高级搜索实现多条件搜索
9.顶部与刷新与视图列
10.实现文本类型明细行
11.列的统计
12.隐藏列,时间日期列格式化
13.新窗口打开
14.随机数据
15.自由编辑
16.清空数据
17.模板下载

截图

基础工程

表格组件导出 Excel Word Html Pdf

Wiki - Gitee.com

注入FreeSqlDataService服务,支持全数据导出

更新包



Program.cs 添加代码

using Densen.DataAcces.FreeSql;
builder.Services.AddSingleton(typeof(FreeSqlDataService<>));
builder.Services.ConfigureJsonLocalizationOptions(op =>
{
    // 忽略文化信息丢失日志
    op.IgnoreLocalizerMissing = true;
});

Index.razor添加一个 TabItem

Tab 顺便改为懒加载

 
    ...
    
        
    

添加打印预览Pages_Host.cshtml

< / body > 前加一句

    

数据实体类DataSalesChannels.cs

查看代码

using BootstrapBlazor.Components;
using DocumentFormat.OpenXml.Wordprocessing;
using FreeSql.DataAnnotations;
using Magicodes.ExporterAndImporter.Excel;
using OfficeOpenXml.Table;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;


namespace b14table.Data;

[ExcelImporter(IsLabelingError = true)]
[ExcelExporter(Name = "导入商品中间表", TableStyle = TableStyles.Light10, AutoFitAllColumn = true)]
[AutoGenerateClass(Searchable = true, Filterable = true, Sortable = true, ShowTips = true)]

public class SalesChannels
{
    [AutoGenerateColumn(Ignore = true)]
    [Column(IsIdentity = true)]
    [DisplayName("序号")]
    public int ID { get; set; }

    [AutoGenerateColumn(ComponentType = typeof(ColorPicker), Width = 30)]
    [DisplayName("级别")]
    public string? Background { get; set; }

    [AutoGenerateColumn(FormatString = "yyyy-MM-dd")]
    [DisplayName("日期")]
    public DateTime Date { get; set; }

    [Required(ErrorMessage = "{0}不能为空")]
    [DisplayName("名称")]
    public string? Name { get; set; }

    [DisplayName("项目数量")]
    public int Projects { get; set; }

    [DisplayName("交单数量")]
    public int Orders { get; set; }

    [DisplayName("结单数量")]
    public int Checkouts { get; set; }

    // 编辑界面无法显示小数, 以后再思考
    [DisplayName("结单率")]
    [AutoGenerateColumn(Readonly = true)]
    public string? CheckoutRates { get => GetCheckoutRates(Checkouts, Orders); set => checkoutRates = value; }
    string? checkoutRates;


    [DisplayName("合格数量")]
    public int Qualifieds { get; set; }

    [DisplayName("合格率")]
    [AutoGenerateColumn(Readonly = true)]
    public string? QualifiedRates { get => GetQualifiedRates(Qualifieds, Checkouts); set => qualifiedRates = value; }
    string? qualifiedRates;

    [DisplayName("总价值")]
    public int Total { get; set; }

    [DisplayName("应收款")]
    public int Receivables { get; set; }

    [DisplayName("已收款")]
    public int Received { get; set; }

    [AutoGenerateColumn(FormatString = "HH:mm:ss")]
    [DisplayName("修改日期")]
    public DateTime ModifiedDate { get; set; } = DateTime.Now;

    [AutoGenerateColumn(TextEllipsis = true, Visible = false, ShowTips = true, ComponentType = typeof(Textarea))]
    [DisplayName("备注")]
    public string? Remark { get; set; }

    [AutoGenerateColumn(Visible = false, ComponentType = typeof(BootstrapInput), Width = 80)]
    [DisplayName("Test1")]
    public decimal Test1 { get; set; }

    private string GetCheckoutRates(int checkouts, int orders) => orders > 0 ? (checkouts /(double) orders).ToString("P2") : "0%";

    private string GetQualifiedRates(int qualifieds, int checkouts) => checkouts > 0 ? (qualifieds / (double)checkouts).ToString("P2") : "0%";


}

页面PagesImpExpIII.razor

查看代码

@page "/impexpiii"
@using b14table.Data 
@using static Blazor100.Service.ImportExportsService

综合演示



备注: @context.Remark ExportExcelAsync(list1.Rows)"> Excel ExportWordAsync(list1.Rows)"> Word ExportHtmlAsync(list1.Rows)"> Html ExportPDFAsync(list1.Rows)"> PDF ExportExcelAsync(DataService.GetAllItems())"> Excel ExportWordAsync(DataService.GetAllItems())"> Word ExportHtmlAsync(DataService.GetAllItems())"> Html ExportPDFAsync(DataService.GetAllItems())"> PDF

页面代码PagesImpExpIII.razor

查看代码

using AmeBlazor.Components;
using b14table.Data;
using Blazor100.Service;
using BootstrapBlazor.Components;
using Densen.DataAcces.FreeSql;
using DocumentFormat.OpenXml.Spreadsheet;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.JSInterop;
using System.Diagnostics.CodeAnalysis;
using static Blazor100.Service.ImportExportsService;

namespace b14table.Pages
{
    public partial class ImpExpIII
    {

        [Inject]
        IWebHostEnvironment? HostEnvironment { get; set; }

        [Inject]
        [NotNull]
        NavigationManager? NavigationManager { get; set; }

        [Inject]
        [NotNull]
        ImportExportsService? ImportExportsService { get; set; }

        [Inject]
        [NotNull]
        ToastService? ToastService { get; set; }

        [Inject]
        [NotNull]
        FreeSqlDataService? DataService { get; set; }

        [NotNull]
        Table? list1 { get; set; }

        [Parameter] public int Footercolspan1 { get; set; } = 3;

        [Parameter] public int Footercolspan2 { get; set; } = 2;

        [Parameter] public int Footercolspan3 { get; set; }

        [Parameter] public int FootercolspanTotal { get; set; } = 2;

        [Parameter] public string? FooterText { get; set; } = "合计:";

        [Parameter] public string? FooterText2 { get; set; }

        [Parameter] public string? FooterText3 { get; set; }

        [Parameter] public string? FooterTotal { get; set; }

        /// 
        /// 获得/设置 IJSRuntime 实例
        /// 
        [Inject]
        [NotNull]
        protected IJSRuntime? JsRuntime { get; set; }
        [Parameter] public string? 新窗口打开Url { get; set; } = "https://localhost:7292/";

        // 由于使用了FreeSql ORM 数据服务,可以直接取对象
        [Inject]
        [NotNull]
        IFreeSql? fsql { get; set; }

        [Inject] ToastService? toastService { get; set; }
        [Inject] SwalService? SwalService { get; set; }


        public bool IsExcel { get; set; }
        public bool DoubleClickToEdit { get; set; } = true;
        protected string UploadPath = "";
        protected string? uploadstatus;
        long maxFileSize = 1024 * 1024 * 15;
        string? tempfilename;

        private AggregateType Aggregate { get; set; }
        
        protected async Task GetDatasAsync()
        {
            var datas = GetDemoDatas();
            await fsql.Insert().AppendData(datas).ExecuteAffrowsAsync();
            await list1!.QueryAsync();
        }

        protected override async void OnAfterRender(bool firstRender)
        {
            if (firstRender)
            {
                UploadPath = Path.Combine(HostEnvironment!.WebRootPath, "uploads");
                if (!Directory.Exists(UploadPath)) Directory.CreateDirectory(UploadPath);
                await list1!.QueryAsync();
            }
        }

        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if (firstRender)
            {
                //懒的人,直接初始化一些数据用用
                var res = fsql.Select().Count();
                if (res == 0)
                {
                    var datas = GetDemoDatas();
                    await fsql.Insert().AppendData(datas).ExecuteAffrowsAsync();
                    await list1!.QueryAsync();
                }
            }
        }

        public List GetDemoDatas()
        {

            var list = new List();
            for (int i = 0; i < 100; i++)
            {
                try
                {
                    var total = Random.Shared.Next(100, 3000);
                    list.Add(new SalesChannels()
                    {
                        ID = i,
                        Name = "渠道" + i,
                        Date = DateTime.Now,
                        Projects = Random.Shared.Next(10, 55),
                        Orders = Random.Shared.Next(3, 10),
                        Qualifieds = i,
                        Total = total,
                        Receivables = total - i,
                        Received = i,
                        Remark= #34;{i} 明细行内嵌套另外一个 Table 组件,由于每行都要关联子表数据,出于性能的考虑,此功能采用 懒加载 模式,即点击展开按钮后,再对嵌套 Table 进行数据填充,通过 ShowDetailRow 回调委托可以控制每一行是否显示明细行,本例中通过 Complete 属性来控制是否显示明细行,可通过翻页来测试本功能"
                    });

                }
                catch (Exception e)
                {
                    System.Console.WriteLine(e.Message);
                }
            }
            return list;

        }

        private Task IsExcelToggle()
        {
            IsExcel = !IsExcel;
            DoubleClickToEdit = !IsExcel;
            StateHasChanged();
            return Task.CompletedTask;
        }

        public async Task Export模板Async()
        {
            await Export();
            return true;
        }

        private async Task ExportExcelAsync(IEnumerable items) => await ExportAutoAsync(items, ExportType.Excel);
        private async Task ExportPDFAsync(IEnumerable items) => await ExportAutoAsync(items, ExportType.Pdf);
        private async Task ExportWordAsync(IEnumerable items) => await ExportAutoAsync(items, ExportType.Word);
        private async Task ExportHtmlAsync(IEnumerable items) => await ExportAutoAsync(items, ExportType.Html);

        private async Task ExportAutoAsync(IEnumerable items, ExportType exportType = ExportType.Excel)
        {
            if (items == null || !items.Any())
            {
                await ToastService.Error("提示", "无数据可导出");
                return false;
            }
            var option = new ToastOption()
            {
                Category = ToastCategory.Information,
                Title = "提示",
                Content = #34;导出正在执行,请稍等片刻...",
                IsAutoHide = false
            };
            // 弹出 Toast
            await ToastService.Show(option);
            await Task.Delay(100);


            // 开启后台进程进行数据处理
            await Export(items?.ToList(), exportType);

            // 关闭 option 相关联的弹窗
            option.Close();

            // 弹窗告知下载完毕
            await ToastService.Show(new ToastOption()
            {
                Category = ToastCategory.Success,
                Title = "提示",
                Content = #34;导出成功,请检查数据",
                IsAutoHide = false
            });
            return true;

        }

        private async Task Export(List? items = null, ExportType exportType = ExportType.Excel)
        {
            try
            {
                if (items == null || !items.Any())
                {
                    ToastService?.Error(#34;导出", #34;{exportType}出错,无数据可导出");
                    return;
                }
                var fileName = items == null ? "模板" : typeof(SalesChannels).Name;
                var fullName = Path.Combine(UploadPath, fileName);
                fullName = await ImportExportsService.Export(fullName, items, exportType);
                fileName = (new System.IO.FileInfo(fullName)).Name;
                ToastService?.Success("提示", fileName + "已生成");

                //下载后清除文件
                NavigationManager.NavigateTo(#34;uploads/{fileName}", true);
                _ = Task.Run(() =>
                {
                    Thread.Sleep(50000);
                    System.IO.File.Delete(fullName);
                });

            }
            catch (Exception e)
            {
                ToastService?.Error(#34;导出", #34;{exportType}出错,请检查. {e.Message}");
            }
        }

        public async Task EmptyAll()
        {
            fsql.Delete().Where(a => 1 == 1).ExecuteAffrows();
            await ToastService!.Show(new ToastOption()
            {
                Category = ToastCategory.Success,
                Title = "提示",
                Content = "已清空数据",
            });

            await list1!.QueryAsync();
            return true;
        }
        private async Task ImportExcel()
        {
            if (string.IsNullOrEmpty(tempfilename))
            {
                ToastService?.Error("提示", "请正确选择文件上传");
                return;
            }
            var option = new ToastOption()
            {
                Category = ToastCategory.Information,
                Title = "提示",
                Content = "导入文件中,请稍等片刻...",
                IsAutoHide = false
            };
            // 弹出 Toast
            await ToastService!.Show(option);
            await Task.Delay(100);


            // 开启后台进程进行数据处理
            var isSuccess = await MockImportExcel();

            // 关闭 option 相关联的弹窗
            option.Close();

            // 弹窗告知下载完毕
            await ToastService.Show(new ToastOption()
            {
                Category = isSuccess ? ToastCategory.Success : ToastCategory.Error,
                Title = "提示",
                Content = isSuccess ? "操作成功,请检查数据" : "出现错误,请重试导入或者上传",
                IsAutoHide = false
            });

            await list1!.QueryAsync();
        }
        private async Task MockImportExcel()
        {
            var items_temp = await ImportExportsService!.ImportFormExcel(tempfilename!);
            if (items_temp.items == null)
            {
                ToastService?.Error("提示", "文件导入失败: " + items_temp.error);
                return false;
            }
            //items = SmartCombine(items_temp, items).ToList(); 新数据和老数据合并处理,略100字
            await fsql.Insert().AppendData(items_temp!.items.ToList()).ExecuteAffrowsAsync();
            return true;
        }

        protected async Task OnChange(InputFileChangeEventArgs e)
        {
            if (e.File == null) return;
            tempfilename = Path.Combine(UploadPath, e.File.Name);
            await using FileStream fs = new(tempfilename, FileMode.Create);
            using var stream = e.File.OpenReadStream(maxFileSize);
            await stream.CopyToAsync(fs);

            //正式工程此处是回调,简化版必须InvokeAsync一下,自由发挥
            _ = Task.Run(async () => await InvokeAsync(async () => await ImportExcel()));

        }

        /// 
        /// 导出数据方法
        /// 
        /// 
        /// 
        /// 
        protected async Task ExportAsync(IEnumerable Items, QueryPageOptions opt)
        {
            var ret = await ExportExcelAsync(Items);
            return ret;
        }

        public Task PrintPreview(IEnumerable item)
        {
            //实际工程自己完善js打印
            JsRuntime.InvokeVoidAsync("printDiv");
            return Task.CompletedTask;
        }

        private Task 新窗口打开()
        {
            if (string.IsNullOrEmpty(新窗口打开Url))
            {
                ToastService?.Error("提示", "Url为空!");
                return Task.CompletedTask;
            }
            JsRuntime.NavigateToNewTab(新窗口打开Url);
            return Task.CompletedTask;
        }

        public async Task 批量审批(IEnumerable items)
        {
            items.ToList().ForEach(a =>
            {
                a.Checkouts = a.Orders;
                a.Receivables = 0;
                a.Received = a.Total;
                a.ModifiedDate = DateTime.Now;
            });
            var res = await fsql.Update().SetSource(items).ExecuteAffrowsAsync();

            await SwalService!.Show(new SwalOption()
            {
                Title = res == 0 ? "提示: 操作失败" : "提示: 操作成功"

            });
           if (res != 0) await list1!.QueryAsync();

        }



    }
}

预览

源代码

https://gitee.com/densen2014/Blazor100/tree/master/b04table

https://git可hu删b.com/densen2014/Blazor100/tree/master/b04table

项目地址

https://gitee.com/LongbowEnterprise/BootstrapBlazor

项目Wiki

https://gitee.com/LongbowEnterprise/BootstrapBlazor/wikis/QuickStart/[硬核] Table 综合演示例子?sort_id=7452536

关联项目

FreeSql

BA & Blazor

知识共享许可协议

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名AlexChow,不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系 。

转载声明

本文来自博客园,作者:周创琳 AlexChow,转载请注明原文链接:https://www.cnblogs.com/densen2014/p/17053020.html

AlexChow

今日头条 | 博客园 | 知乎 | Gitee

展开阅读全文

页面更新:2024-05-01

标签:数据处理   批量   新窗口   演示   例子   数量   提示   编辑   日期   代码   项目   数据

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top