原本使用「Microsoft.Office.Interop.Excel」套件 但寫一寫出現"HRESULT: 0x800A03EC"錯誤訊息 上網查一查,看到有人推薦EPPlus這套件 就載來試試並且換個簡單方法撰寫。 ### 前端.xmal設計匯出如下: ``` <StackPanel Orientation="Horizontal" Margin="0 8 8 0" VerticalAlignment="Center" HorizontalAlignment="Right"> <Button Style="{StaticResource PageFuncIconButton}" Content="{materialDesign:PackIcon Kind=FileExport, Size=36}" Command="{Binding ExportCommand}" CommandParameter="{Binding ElementName=MyDataGrid}" ToolTip="匯出" /> </StackPanel> ``` 可愛的匯出圖案 ![image](https://hackmd.io/_uploads/HyJgQmzMC.png) ### viewModel.cs寫法如下(並不是用Click的方式): ``` public ICommand ExportCommand { get { if (exportCommand == null) exportCommand = new RelayCommand(Export); return exportCommand; } } ``` #### Export(): 因為匯出功能想要當作共用,因此開新的檔案來撰寫此功能。 ``` public DataGrid MyDataGrid { get; set; } ExportExcel exportexcel = null; private void Export() { if (exportexcel == null) exportexcel = new ExportExcel(); if (QueryItemResults != null && QueryItemResults.Any()) { exportexcel.ExportDataExcel(QueryItemResults); } } ``` #### ExportExcel.cs ``` using CommunityToolkit.Mvvm.Messaging; using OfficeOpenXml; using PIDC_LMS.Messages; using PIDC_LMS.Models; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web.UI.WebControls; using System.Windows; using static log4net.Appender.RollingFileAppender; ``` **註記:** 1.原先自動抓欄位的屬性,因欄位名稱都固定,因此直接設計Cells[1列, 1欄].Value欄位 2.<font color="blue">儲存格是從1開始數</font> 3.原先抓DataGrid的寫法會讓日期格式的值跑掉,因此改寫另一種日期格式寫法 4.獲取當前時間,將時間寫在檔名中,是為了避免每次匯出,會覆蓋前一次內容 5.匯出後跳出一個視窗,告訴使用者已匯出完畢 ``` namespace PIDC_LMS.Libs { public class ExportExcel { public void ExportDataExcel(ObservableCollection<QueryItem> queryItems) { ExcelPackage.LicenseContext = LicenseContext.NonCommercial; // 關閉新許可模式通知 // 獲取當前日期時間的時間戳 string timeStamp = DateTime.Now.ToString("yyyyMMddHHmmss"); // 在文件名中添加時間戳,可以避免檔案覆蓋 var file = new FileInfo(@"D:\匯出_" + timeStamp + ".xlsx"); using (var excel = new ExcelPackage()) { // 建立分頁 var ws = excel.Workbook.Worksheets.Add("MySheet"); #region 自動抓欄位屬性 //int rowindex = 1; //int colindex = 1; //foreach (var pp in typeof(QueryItem).GetProperties()) //{ // ws.Cells[rowindex,colindex].Value = pp.Name; // colindex++; //} #endregion // 設置中文欄位名稱 ws.Cells[1, 1].Value = "條碼號"; ws.Cells[1, 2].Value = "書名"; ws.Cells[1, 3].Value = "狀態"; ws.Cells[1, 4].Value = "借閱次數"; ws.Cells[1, 5].Value = "借閱者"; ws.Cells[1, 6].Value = "借閱日期"; ws.Cells[1, 7].Value = "歸還日期"; ws.Cells[1, 8].Value = "建檔日期"; //寫入資料 int rowindex = 2; foreach (var item in queryItems) { //colindex = 1; //foreach (var pp in typeof(QueryItem).GetProperties()) //{ // ws.Cells[rowindex, colindex].Value =pp.GetValue(item); // colindex++; //} //rowindex++; ws.Cells[rowindex, 1].Value = item.ItemID; ws.Cells[rowindex, 2].Value = item.ItemName; // 狀態欄位根據您的邏輯來填寫 ws.Cells[rowindex, 3].Value = item.ItemState == "03" ? "在庫" : "已借閱"; ws.Cells[rowindex, 4].Value = item.CheckOutTimes; ws.Cells[rowindex, 5].Value = item.CheckOutPatronName; // 借閱日期和歸還日期套用格式 ws.Cells[rowindex, 6].Value = ((DateTime)item.CheckOutDateTime).ToString("yyyy-MM-dd HH:mm:ss"); ws.Cells[rowindex, 7].Value = ((DateTime)item.CheckOutDueDate).ToString("yyyy-MM-dd"); //ws.Cells[rowindex, 8].Value = item.CreatedDateTime.ToString("yyyy-MM-dd HH:mm:ss"); rowindex++; } // 儲存 Excel excel.SaveAs(file); MessageBox.Show("匯出成功!", "成功", MessageBoxButton.OK, MessageBoxImage.Information); } } } } ``` ### 參考資料 [EPPlus —— 輕鬆處理 Excel](https://igouist.github.io/post/2020/04/epplus/#%E5%BB%BA%E7%AB%8B-excel)