这两种方法目前如果遇到0开头的数据,会默认把0去掉,可以考虑如果StartsWith(“0”),则在前面加个单引号(即’)
不推荐Excel导出,因为Excel2003一个Sheet最多导出65535条,Excel2007是10万4000多条,数据量大会报错,所以推荐使用CSV导出

  • 导出 Excel
    /// <summary>
    /// 将 DataTable 转换为 Excel
    /// 需在 nuget 安装 DotNetCore.NPOI
    /// </summary>
    /// <param name="table">数据表</param>
    /// <param name="sheetName">sheet名称</param>
    /// <returns></returns>
    public static byte[] DataTableToExcel(DataTable table, string title = null, string sheetName = "Sheet")
    {
        try
        {
            IWorkbook workbook = new XSSFWorkbook();
            ISheet sheet = workbook.CreateSheet(sheetName);
            int cellsIndex = 0;
            // 标题
            if (!string.IsNullOrEmpty(title))
            {
                // 填充数据
                IRow cellsTitle = sheet.CreateRow(0);
                cellsTitle.CreateCell(0).SetCellValue(title);
                // 合并单元格
                sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 1, 0, table.Columns.Count - 1));
                cellsIndex = 2;
            }
            // 填充表头
            IRow cellsHeader = sheet.CreateRow(cellsIndex);
            for (int i = 0; i < table.Columns.Count; i++)
            {
                cellsHeader.CreateCell(i).SetCellValue(table.Columns[i].ColumnName);
            }
            // 填充数据
            cellsIndex += 1;
            foreach (DataRow dr in table.Rows)
            {
                IRow row = sheet.CreateRow(cellsIndex);
                for (int i = 0; i < table.Columns.Count; i++)
                {
                    row.CreateCell(i).SetCellValue(StrHelper.ToString(dr[i]));
                }
                cellsIndex++;
            }
            byte[] buffer = null;
            using (MemoryStream ms = new MemoryStream())
            {
                workbook.Write(ms);
                buffer = ms.GetBuffer();
                ms.Close();
            }
            return buffer;
        }
        catch (Exception)
        {
            return null;
        }
    }	
    
  • 导出 CSV
    /// <summary>
    /// 将 DataTable 转换为 CSV
    /// </summary>
    /// <param name="table">数据表</param>
    /// <returns></returns>
    public static Stream DataTableToCsv(DataTable table)
    {
        try
        {
            StringBuilder builder = new StringBuilder();
            DataColumn column;
            int iColCount = table.Columns.Count;
            // 处理表头
            for (int i = 0; i < iColCount; i++)
            {
                if (i != 0) builder.Append(",");
                builder.Append("\"" + table.Columns[i].ColumnName + "\"");
            }
            builder.AppendLine();
            // 处理内容
            foreach (DataRow row in table.Rows)
            {
                for (int i = 0; i < iColCount; i++)
                {
                    column = table.Columns[i];
                    if (i != 0) builder.Append(",");
                    if (Convert.IsDBNull(row[column])) builder.Append("\"\"");
                    //else if (row[column].ToString().StartsWith("0")) builder.Append("\"'" + row[column].ToString() + "\"");
                    else builder.Append("\"" + row[column].ToString() + "\"");
                }
                builder.AppendLine();
            }
            byte[] bytes = Encoding.GetEncoding("GB2312").GetBytes(builder.ToString());
            Stream stream = new MemoryStream(bytes);
            return stream ;
        }
        catch (Exception)
        {
            return null;
        }
    }
    
  • .Net Core WebAPI Controller
    /// <summary>
    /// 导出 Excel
    /// </summary>
    /// <returns></returns>
    [HttpGet("exportExcel")]
    public async Task<IActionResult> ExportExcel()
    {
        DataTable dataTable = new DataTable(); // 此处准备 dataTable 数据
        
        string name = "数据详情";
        byte[] bytes = Utils.DataTableToExcel(dataTable, name, name);
        return File(bytes, "application/octet-stream", $"{name}_{DateTime.Now:yyyyMMddHHmmssfff}.xlsx");
    }
    
    /// <summary>
    /// 导出 CSV
    /// </summary>
    /// <returns></returns>
    [HttpGet("exportCSV")]
    public async Task<IActionResult> ExportCSV()
    {
        DataTable dataTable = new DataTable(); // 此处准备 dataTable 数据
    
        System.IO.Stream stream = Utils.DataTableToCsv(dataTable);
        return File(stream, "application/octet-stream", $"数据详情_{DateTime.Now:yyyyMMddHHmmssfff}.csv");
    }
    
  • .Net Core Startup.cs 配置
    这里配置 .WithExposedHeaders("Content-Disposition")
    是因为 Vue Axios response.headers 中默认获取不到 content-disposition 属性
    点击此处查看microsoft官方文档
    public void ConfigureServices(IServiceCollection services)
    {
    	// ......
    	
        // 处理 api 请求跨域
        services.AddCors(options =>
        {
            options.AddPolicy("cors",
                builder =>
                {
                    builder.AllowAnyMethod()
                    .AllowAnyOrigin()
                    .AllowAnyHeader()
                    .WithExposedHeaders("Content-Disposition");
                });
        });
    
    	// ......
    }
    
  • Vue Axios
    service.interceptors.response.use(
      response => {
        // blob 直接返回文件流数据
        if (response.config.responseType === 'blob') {
          console.log(response.headers);
          const fileName = decodeURI(
          	// response.headers['content-disposition'] 默认获取不到,需要在 .Net Core Startup.cs 中进行配置
            response.headers['content-disposition'].split('filename*=UTF-8\'\'')[1]
          )
          return Promise.resolve({ data: response.data, fileName: fileName })
        }
    
        // ......
      },
      error => {
        return Promise.reject(error)
      }
    )
    
  • Vue 请求接口
    export function exportCSV(param) {
        return request({
            url: '/controller/exportCSV',
            method: 'get',
            params: { ...param },
            responseType: 'blob'
        })
    }
    
  • Vue 下载实现
    export default {
      data() {
        return {
          listQuery: {},
        };
      },
      created() {},
      methods: {
        // 导出报表
        onExport() {
          exportCSV(this.listQuery).then((response) => {
            let blob = new Blob([response.data], { type: response.data.type });
            // 针对于 IE 浏览器的处理, 因部分 IE 浏览器不支持 createObjectURL
            if (window.navigator && window.navigator.msSaveOrOpenBlob) {
              window.navigator.msSaveOrOpenBlob(blob, response.fileName);
            } else {
              var downloadElement = document.createElement("a");
              var href = window.URL.createObjectURL(blob); // 创建下载的链接
              downloadElement.href = href;
              downloadElement.download = response.fileName; // 下载后文件名
              document.body.appendChild(downloadElement);
              downloadElement.click(); // 点击下载
              document.body.removeChild(downloadElement); // 下载完成移除元素
              window.URL.revokeObjectURL(href); // 释放掉 blob 对象
            }
          });
        },
      },
    };
    
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐