硬核BootstrapBlazorTable综合演示例子
知识点:
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 综合演示
true" ShowCardView="true" ShowColumnList="true" ShowFooter="true" ScrollingDialogContent="true" EditDialogIsDraggable="true" EditDialogSize="Size.ExtraLarge" EditDialogShowMaximizeButton="true" ShowExportButton OnExportAsync="ExportAsync" PageItemsSource="new int[] {10, 20, 50, 100, 200, 500, 1000 }"> 备注: @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.htmlAlexChow
今日头条 | 博客园 | 知乎 | Gitee