abp框架Excel匯出——基於vue
1.技術棧
1.1 前端採用vue,官方提供
UI套件用的是iview
1.2 後臺是abp——aspnetboilerplate
即abp v1,https://github.com/aspnetboilerplate/aspnetboilerplate。 下載時選擇的是net core 3.1。
2. Excel匯出需求
管理後臺系統,主要以圖表統計形式歸檔資料,使用者經常會有Excel匯出報表的需求。可以以檔案形式儲存,更加地直觀,符合使用習慣。
3. 升級日誌Excel匯出
物聯網中的裝置是核心資產,而維護裝置經常需要一些升級割接操作,因此,升級日誌(升級失敗,升級成功,升級時間)等是使用者比較關心的資料。
4. 技術實現方案
4.1 後臺
4.1.1 EPPlus匯出靜態方法
需要nuget安裝EPPlus.Core庫。運用了委託的方法方便地實現了對匯出表單進行新增標題,填充內容資料,渲染單元格樣式,委託的一大優勢就是方便呼叫,層次感很明顯。該方法如果看得還不是很明白,請耐心繼續往下看。
public abstract class EPPlusExcelExporterBase : AbpServiceBase
{
protected EPPlusExcelExporterBase( )
{}
public static byte[] CreateExcelPackage(string fileName, Action<ExcelPackage> creator)
{
var excelPackage = new ExcelPackage();
creator(excelPackage);
using (var stream = new MemoryStream())
{
excelPackage.SaveAs(stream);
excelPackage.Dispose();
return stream.ToArray();
}
}
public static void AddHeader(ExcelWorksheet sheet, params string[] headerTexts)
{
if (headerTexts.IsNullOrEmpty())
{
return;
}
for (var i = 0; i < headerTexts.Length; i++)
{
AddHeader(sheet, i + 1, headerTexts[i]);
}
}
protected static void AddHeader(ExcelWorksheet sheet, int columnIndex, string headerText)
{
sheet.Cells[1, columnIndex].Value = headerText;
sheet.Cells[1, columnIndex].Style.Font.Bold = true;
}
public static void AddObjects<T>(ExcelWorksheet sheet, int startRowIndex, IList<T> items, params Func<T, object>[] propertySelectors)
{
if (items.IsNullOrEmpty() || propertySelectors.IsNullOrEmpty())
{
return;
}
for (var i = 0; i < items.Count; i++)
{
for (var j = 0; j < propertySelectors.Length; j++)
{
sheet.Cells[i + startRowIndex, j + 1].Value = propertySelectors[j](items[i]);
}
}
}
}
4.1.2 生成升級日誌列表
此部分程式碼與主業務相關,因為原本業務與區域許可權有關,簡化起見,故刪除其他無關程式碼,主要就是從資料庫獲取了升級列表,並且按照了升級時間進行了倒序排列。讀者不同的業務可進行不同操作。需要轉義的轉義,聯表的聯表,過濾的過濾,排序的排序。
var dbQuery = from upgradeLog in _fsuUpgradeResultRepository.GetAll();
var UpgradeLogDtoList = await dbQuery
.OrderByDescending(x => x.Updatetime)
.ToListAsync();
4.1.3 將升級日誌列表放到Excel匯出靜態方法中去
var data= EPPlusExcelExporterBase.CreateExcelPackage(
"UpgradeLog.xlsx",
excelPackage =>
{
var sheet = excelPackage.Workbook.Worksheets.Add("UpgradeLog");
sheet.OutLineApplyStyle = true;
EPPlusExcelExporterBase.AddHeader(
sheet,
"Fsu資產編碼",
"升級結果",
"是否反饋",
"Fsu IP地址",
"更新時間"
);
EPPlusExcelExporterBase.AddObjects(
sheet, 2, UpgradeLogDtoList,
_ => _.FsuId,
_ => _.Result,
_ => _.IsReport,
_ => _.FsuIp,
_ => _.Updatetime
);
//Formatting cells
var UpdatetimeColumn = sheet.Column(5);
UpdatetimeColumn.Style.Numberformat.Format = "yyyy-mm-dd-hh:mm:ss";
for (var i = 1; i <= 5; i++)
{
sheet.Column(i).AutoFit();
}
});
委託裡面流程分下:新增報表表頭,新增內容,設定顯示樣式(時間格式),新增樣式(設定單元格自適應內容大小)。
通過CreateExcelPackage方法放回了檔案位元流。
4.1.4 abp框架中前後端分離模式檔案流傳輸
以FileResult形式返回前端傳來的請求。需要注意的是FileResult是 Microsoft.AspNetCore.Mvc.Core中的一個類。
public async Task<FileResult> GetUpgradeReport()
{
var dbQuery = from upgradeLog in _fsuUpgradeResultRepository.GetAll();
var UpgradeLogDtoList = await dbQuery
.OrderByDescending(x => x.Updatetime)
.ToListAsync();
foreach (var item in UpgradeLogDtoList)
{
ConvertDto(item);//對升級結果,是否上報鐵塔平臺進行解析
}
var data= EPPlusExcelExporterBase.CreateExcelPackage(
"UpgradeLog.xlsx",
excelPackage =>
{
var sheet = excelPackage.Workbook.Worksheets.Add("UpgradeLog");
sheet.OutLineApplyStyle = true;
EPPlusExcelExporterBase.AddHeader(
sheet,
"Fsu資產編碼",
"升級結果",
"是否反饋",
"Fsu IP地址",
"更新時間"
);
EPPlusExcelExporterBase.AddObjects(
sheet, 2, UpgradeLogDtoList,
_ => _.FsuId,
_ => _.Result,
_ => _.IsReport,
_ => _.FsuIp,
_ => _.Updatetime
);
//Formatting cells
var UpdatetimeColumn = sheet.Column(5);
UpdatetimeColumn.Style.Numberformat.Format = "yyyy-mm-dd-hh:mm:ss";
for (var i = 1; i <= 5; i++)
{
sheet.Column(i).AutoFit();
}
});
var fileContentResult = new FileContentResult(data, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
{
FileDownloadName = "升級日誌報表.xlsx"
};
return fileContentResult;
}
4.2 前端
4.2.1 vuex的action中新增請求方法
程式碼如下:
actions = {
async getUpgradeLogReport(context: ActionContext<UpgradeLogState, any>) {
let data= await Ajax.get('/api/services/app/Upgrade/GetUpgradeReport',{
responseType: 'blob',
headers: {
'Content-Type': 'application/json'
}});
return data;
}
}
告訴後臺以blob形式返回。當然請求方法你也可以直接普通形式封裝,不一定封裝在vuex裡,這裡封裝在vuex的一個好處是有些狀態資料可以儲存在vuex,所有頁面可以共享該資料。
4.2.2 upgradeLog.vue升級頁面
4.2.2.1 增加下載方法
async downloadUpgradeLogReport(){
await this.$store.dispatch({
type: "upgradelog/getUpgradeLogReport"
}).then(res => {
if (res.status == "200") {
var excelBlob = new Blob([res.data], {
type: "application/vnd.ms-excel"
});
var fileName = "升級日誌報表.xlsx";
var oa = document.createElement("a");
oa.href = URL.createObjectURL(excelBlob);
oa.download = fileName;
document.body.appendChild(oa);
oa.click();
}
});
}
建立一個blob物件,以建立url方式將此物件下載。
4.2.2.2 點選匯出報表按鈕呼叫下載方法
<Button @click="downloadUpgradeLogReport()">匯出升級日誌報表</Button>
5. 最終效果
5.1 點選按鈕
5.2 報表展示
6.小結
- 筆者下載使用過多個開源方案匯出Excel,此種方式方法比較輕量,使用比較簡潔;
- 在abp中返回Excel的形式需要思考,因為如果無法繼承ControllerBase,就無法使用ActionResult這種萬能返回形式(C#中只能繼承一個基類,可以繼承多個介面);
- vue中ajax接收Excel返回資料時需要注意設定返回型別為Blob,否則將會下載不成功;
- 這裡Excel匯出是借鑑了Abp Zero 8.1的思路,他是類以瞬時模式注入容器,我是寫成了靜態方法。但是Abp Zero Excel匯出的思路大有不同,首先是生成檔案在Cache裡,然後返回檔案GUID(Token),使用者再拿著GUID(Token)通過fileController從cache匯出需要下載的檔案。快取有效期1分鐘,目的是為了防止有人拿到連結攻擊,不停下載。
版權宣告:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連結和本宣告。
本文連結:https://www.cnblogs.com/JerryMouseLi/p/13399027.html