[硬核] Bootstrap Blazor Table 综合演示例子
知识点:
1.导入导出
2.分页功能
3.增删改查
4.批量删除
5.批量编辑(审核)
6.列排序与列搜索
7.顶部搜索实现所有列搜索
8.高级搜索实现多条件搜索
9.顶部与刷新与视图列
10.实现文本类型明细行
11.列的统计
12.隐藏列,时间日期列格式化
13.新窗口打开
14.随机数据
15.自由编辑
16.清空数据
17.模板下载
截图
基础工程
注入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
前加一句
数据实体类 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 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 = $"导出正在执行,请稍等片刻...",
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 = $"导出成功,请检查数据",
IsAutoHide = false
});
return true;
}
private async Task Export(List? items = null, ExportType exportType = ExportType.Excel)
{
try
{
if (items == null || !items.Any())
{
ToastService?.Error($"导出", $"{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($"uploads/{fileName}", true);
_ = Task.Run(() =>
{
Thread.Sleep(50000);
System.IO.File.Delete(fullName);
});
}
catch (Exception e)
{
ToastService?.Error($"导出", $"{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://github.com/densen2014/Blazor100/tree/master/b04table
项目地址
https://gitee.com/LongbowEnterprise/BootstrapBlazor
项目Wiki
关联项目
FreeSql QQ群:4336577
BA & Blazor QQ群:795206915
知识共享许可协议
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名AlexChow(包含链接: https://github.com/densen2014 ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系 。
转载声明
本文来自博客园,作者:周创琳 AlexChow,转载请注明原文链接:https://www.cnblogs.com/densen2014/p/17053020.html
AlexChow
文章来源于互联网:[硬核] Bootstrap Blazor Table 综合演示例子
THE END
二维码