基於ABP和Magicodes實現Excel匯出操作

2022-08-05 18:01:23

  前端使用的vue-element-admin框架,後端使用ABP框架,Excel匯出使用的Magicodes.IE.Excel.Abp庫。Excel匯入和匯出操作幾乎一樣,不再介紹。文字主要介紹Excel匯出操作和過程中遇到的坑,主要是Excel檔案匯出後無法開啟的問題。

一.Magicodes.IE庫

1.Magicodes.IE庫介紹

  Magicodes.IE是一個匯入匯出的通用庫,它支援Dto匯入匯出、模板匯出、花式匯出以及動態匯出,支援Excel、Csv、Word、Pdf和Html。總之,基本的和高階的匯入和匯出操作都是可以滿足的。主要特點如下:

2.Magicodes.IE庫的NuGet包

Magicodes.IE庫相關的NuGet包如下所示:
(1)Magicodes.IE.Core,v2.6.4
(2)Magicodes.IE.Excel,v2.6.4
(3)Magicodes.IE.Excel.NPOI,v2.6.4
(4)Magicodes.IE.Excel.AspNetCore,v2.6.4
(5)Magicodes.IE.Pdf,v2.6.4
(6)Magicodes.IE.Word,v2.6.4
(7)Magicodes.IE.Html,v2.6.4
(8)Magicodes.IE.Csv,v2.6.4
(9)Magicodes.IE.AspNetCore,v2.6.4
(10)Magicodes.IE.EPPlus,v2.6.4
(11)Magicodes.IE.Excel.Abp,v2.6.4
(12)Magicodes.IE.Csv.Abp,v2.6.4
(13)Magicodes.IE.Html.Abp,v2.6.4
(14)Magicodes.IE.Pdf.Abp,v2.6.4
(15)Magicodes.IE.Word.Abp,v2.6.4

3.Magicodes.IE庫的教學

(1)基礎教學之匯入學生資料[1]
(2)基礎教學之匯出Excel[2]
(3)基礎教學之匯出Pdf收據[3]
(4)在Docker中使用[4]
(5)動態匯出[5]
(6)多Sheet匯入[6]
(7)Csv匯入匯出[7]
(8)Excel圖片匯入匯出[8]
(9)Excel模板匯出之匯出教材訂購表[9]
(10)進階篇之匯入匯出篩選器[10]
(11)Magicodes.IE之花式匯出[11]
(12)Magicodes.IE.AspNetCore之一行程式碼多格式匯出[12]
(13)效能測試[13]
(14)Excel合併行匯入[14]
(15)Excel模板匯出之動態匯出[15]
(16)Magicodes.IE.Excel.AspNetCore之快速匯出Excel[16]

二.基於ABP的Excel匯出操作

1.Business.Application.Contracts

在該專案中新增Magicodes.IE.Excel.Abp類庫。並且BusinessApplicationContractsModule需要依賴MagicodesIEExcelModule模組:
(1)ExportActivityDto類

public class ExportActivityDto : EntityDto<Guid?>
{
    /// <summary>
    /// 姓名或微信暱稱
    /// </summary>
    [Required]
    [ExporterHeader(DisplayName = "姓名或微信暱稱")]
    public string Name { get; set; }

    /// <summary>
    /// 所在省市區
    /// </summary>
    [Required]
    [ExporterHeader(DisplayName = "所在省市區")]
    public string Address { get; set; }

    /// <summary>
    /// 手機號
    /// </summary>
    [Required]
    [ExporterHeader(DisplayName = "手機號")]
    public string Phone { get; set; }

    /// <summary>
    /// 年齡
    /// </summary>
    [Required]
    [ExporterHeader(DisplayName = "年齡")]
    public string Age { get; set; }

    /// <summary>
    /// 備註
    /// </summary>
    [ExporterHeader(DisplayName = "備註")]
    public string Remark { get; set; }
}

(2)IActivityAppService

public interface IActivityAppService : IApplicationService
{
    // 匯出活動列表
    Task<ActionResult> ExportActivity();
}

2.Business.Application

(1)ActivityAppService
通過建構函式注入的方式,依賴注入IExcelExporter:

/// <summary>
/// 通過Excel匯出活動報名資訊
/// </summary>
/// <returns></returns>
public async Task<ActionResult> ExportActivity()
{
    var query = await _repository.GetQueryableAsync();
    var dto = ObjectMapper.Map<List<Activity>, List<ExportActivityDto>>(query.ToList());
    var result = await _excelExporter.ExportAsByteArray(dto);
    var fs  = new MemoryStream(result);

    return new XlsxFileResult(stream: fs, "活動報名資訊表.xlsx");
}

(2)ActivityAutoMapperProfile

public class ActivityAutoMapperProfile : Profile
{
    public ActivityAutoMapperProfile()
    {
        CreateMap<Activity, ExportActivityDto>();
    }
}

3.Business.HttpApi

(1)ActivityController

[HttpGet]
[Route("export-activity")]
public Task<ActionResult> ExportActivity()
{
    return _ActivityAppService.ExportActivity();
}

4.Excel匯出操作vue程式碼

匯出按鈕相關的vue程式碼如下:

<el-button class="filter-item" size="mini" type="success" icon="el-icon-download" @click="handleExport()">匯出</el-button>

匯出函數的vue程式碼如下:

handleExport() {
  var that = this;
  that.$axios.get('/api/app/activity/export-activity').then(res => {
    this.$notify({
      title: '成功',
      message: '匯出成功',
      type: 'success',
      duration: 2000
    });
    var blob = new Blob([res], {
      type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    });
    let url = window.URL.createObjectURL(blob); //建立下載的連結
    let a = document.createElement("a"); //生成一個a標籤
    a.setAttribute("href", url);
    a.setAttribute("download", that.$activityExcelName);
    a.style.display = "none"; //將a標籤隱藏
    document.body.appendChild(a); //將a標籤新增到body中
    a.click(); //觸發a標籤的點選事件
    window.URL.revokeObjectURL(url); //釋放掉blob物件
    a.remove() //將a標籤從body中移除
  }).catch(() => {
    this.$message({
      type: 'info',
      message: '沒有許可權匯出'
    });
  });
  }

其中that.$axios.get中的get()程式碼如下:

get(url) {
  return new Promise((resolve, reject) => {
    axios.get(url, { responseType: "blob" })
      .then(response => {
        resolve(response.data)
      }, err => {
        // Message({
        //   message: err.error.message,
        //   type: 'error',
        //   duration: 5 * 1000
        // })
        reject(err)
      })
      .catch((error) => {
        reject(error)
      })
  })
}

說明:一定要特別注意加上responseType: "blob",否則就會報檔案格式或者副檔名無效的錯誤。自己嘗試了下,換成responseType: "arraybuffer"也是可以的。

三.MagicodesIEXXXModule模組原始碼

1.MagicodesIEExcelModule原始碼

 public class MagicodesIEExcelModule: AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        context.Services.AddScoped<IExcelExporter, ExcelExporter>();
        context.Services.AddScoped<IExcelImporter, ExcelImporter>();
        context.Services.AddScoped<IExportFileByTemplate, ExcelExporter>();
        //TODO:處理篩選器
    }
}

2.MagicodesIECsvModule原始碼

public class MagicodesIECsvModule: AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        context.Services.AddScoped<ICsvExporter, CsvExporter>();
        context.Services.AddScoped<ICsvImporter, CsvImporter>();
    }
}

3.MagicodesIEHtmlModule原始碼

public class MagicodesIEHtmlModule: AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        context.Services.AddScoped<IHtmlExporter, HtmlExporter>();
    }
}

4.MagicodesIEPdfModule原始碼

public class MagicodesIEPdfModule: AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        context.Services.AddScoped<IPdfExporter, PdfExporter>();
    }
}

5.MagicodesIEWordModule原始碼

public class MagicodesIEWordModule: AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        context.Services.AddScoped<IWordExporter, WordExporter>();
    }
}

參考文獻:
[1]基礎教學之匯入學生資料:https://urlify.cn/neI7Vz
[2]基礎教學之匯出Excel:https://urlify.cn/yiei6f
[3]基礎教學之匯出Pdf收據:https://urlify.cn/7FjuA3
[4]在Docker中使用:https://github.com/dotnetcore/Magicodes.IE/blob/master/docs/4.在Docker中使用.md
[5]動態匯出:https://github.com/dotnetcore/Magicodes.IE/blob/master/docs/5.動態匯出.md
[6]多Sheet匯入:https://github.com/dotnetcore/Magicodes.IE/blob/master/docs/6.多Sheet匯入.md
[7]Csv匯入匯出:https://github.com/dotnetcore/Magicodes.IE/blob/master/docs/7.Csv匯入匯出.md
[8]Excel圖片匯入匯出:https://urlify.cn/Ybyey2
[9]Excel模板匯出之匯出教材訂購表:https://urlify.cn/vqyQnq
[10]進階篇之匯入匯出篩選器:https://urlify.cn/Nzmmim
[11]Magicodes.IE之花式匯出:https://urlify.cn/QRZRN3
[12]Magicodes.IE.AspNetCore之一行程式碼多格式匯出:https://github.com/dotnetcore/Magicodes.IE/blob/master/docs/12.Magicodes.IE.AspNetCore之一行程式碼多格式匯出.md
[13]效能測試:https://github.com/dotnetcore/Magicodes.IE/blob/master/docs/13.效能測試.md
[14]Excel合併行匯入:https://github.com/dotnetcore/Magicodes.IE/blob/master/docs/Excel合併行匯入.md
[15]Excel模板匯出之動態匯出:https://github.com/dotnetcore/Magicodes.IE/blob/master/docs/Excel模板匯出之動態匯出.md
[16]Magicodes.IE.Excel.AspNetCore之快速匯出Excel:https://github.com/dotnetcore/Magicodes.IE/blob/master/docs/AspNetCore之快速匯出Excel.md
[17]麥扣官方檔案:https://docs.xin-lai.com/
[18]新增對Abp Vnext模組的封裝和支援:https://github.com/dotnetcore/Magicodes.IE/issues/318
[19]abp框架Excel匯出--基於vue:https://www.cnblogs.com/JerryMouseLi/p/13399027.html
[20]abp-vue匯入匯出excel:https://cloud.tencent.com/developer/article/1552255
[21]使用Magicodes.IE快速匯出Excel:https://www.cnblogs.com/codelove/p/15117226.html
[22]dotnetcore/Magicodes.IE:https://github.com/dotnetcore/Magicodes.IE