string fileName = $"記錄_{DateTime.Now.ToString("yyyyMMdd_HHmmss")}";
string saveFileName = "";
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.DefaultExt = "xls";
//saveFileDialog.Filter = "Excel 工作簿|*.xlsx|Excel 97-2003 工作簿|*.xls";
saveFileDialog.Filter = "Excel 97-2003 工作簿|*.xls";
saveFileDialog.FileName = fileName;
saveFileDialog.ShowDialog();
saveFileName = saveFileDialog.FileName;
if (saveFileName?.IndexOf(":") < 0) return;//點擊了取消
public enum StyleXlsEnum
{
Head,
ColumnHead,
Default
}
private static IWorkbook m_workbook;
private static ISheet m_sheet;
private static List<string> m_sheets = new List<string>();
private static ICellStyle m_cellStyle;
private static IDataFormat m_dataStyle;
private static IFont m_font16;
private static IFont m_font12;
private static IFont m_font;
/// <summary>
/// 導出Excel
/// </summary>
/// <param name="dt">DataTable數據</param>
/// <param name="saveFileName">Excel文件全路徑</param>
/// <param name="sheetName">Sheet名稱</param>
/// <param name="headerName">標題名稱</param>
/// <returns></returns>
private bool ExportExcel(DataTable dt, string saveFileName, string sheetName, string headerName)
{
ICellStyle cellStyle = null;try
{
#region 創建Excel對象
//如果Excel存在就獲取IWorkbook對象,否則就重新創建
if (File.Exists(saveFileName))
{
FileStream fs = new FileStream(saveFileName, FileMode.Open, FileAccess.Read);
m_workbook = new XSSFWorkbook(fs);
if (saveFileName.IndexOf(".xlsx") > 0) // 2007版本
m_workbook = new XSSFWorkbook(fs);
else if (saveFileName.IndexOf(".xls") > 0) // 2003版本
m_workbook = new HSSFWorkbook(fs);
}
else
{
//創建一個工作簿
m_workbook = new HSSFWorkbook();
}
if (m_workbook != null)
{
//獲取所有SheetName
int count = m_workbook.NumberOfSheets;
if (count < 1)
{
m_sheet = m_workbook.CreateSheet(sheetName);
}
else
{
m_sheets.Clear();
for (int i = 0; i < count; i++)
{
m_sheet = m_workbook.GetSheetAt(1);
m_sheets.Add(m_sheet.SheetName);
}
if (m_sheets.Contains(sheetName))
{
m_sheet = m_workbook.CreateSheet(sheetName + System.DateTime.Now.ToString("HH-mm-ss") + "副本");
}
else
{
m_sheet = m_workbook.CreateSheet(sheetName);
}
}
}
else
{
return false;
}
#endregion
#region 設置表頭
m_sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, dt.Columns.Count - 1)); //合並單元格
IRow row0 = m_sheet.CreateRow(0); //創建一行
row0.Height = 50 * 20;
ICell icelltop0 = row0.CreateCell(0); //創建一個單元格
IFont font = m_workbook.CreateFont();
font.FontHeightInPoints = 30;
icelltop0.CellStyle = Getcellstyle(m_workbook, StyleXlsEnum.Head);
icelltop0.SetCellValue(headerName);
#endregion
// 設置列寬,excel列寬每個像素是1/256
m_sheet.SetColumnWidth(0, 9 * 256);
m_sheet.SetColumnWidth(1, 18 * 256);
m_sheet.SetColumnWidth(2, 36 * 256);
m_sheet.SetColumnWidth(3, 25 * 256);
m_sheet.SetColumnWidth(4, 20 * 256);
m_sheet.SetColumnWidth(5, 20 * 256);
m_sheet.SetColumnWidth(6, 20 * 256);
m_sheet.SetColumnWidth(7, 25 * 256);
m_sheet.SetColumnWidth(8, 25 * 256);
m_sheet.SetColumnWidth(9, 25 * 256);
m_sheet.SetColumnWidth(10, 25 * 256);
#region 設置列
IRow rowH = m_sheet.CreateRow(1);
cellStyle = Getcellstyle(m_workbook, StyleXlsEnum.ColumnHead);
//設置列名
foreach (DataColumn col in dt.Columns)
{
//創建單元格並設置單元格內容
rowH.CreateCell(col.Ordinal).SetCellValue(col.Caption);
//設置單元格格式
rowH.Cells[col.Ordinal].CellStyle = cellStyle;
}
#endregion
#region 寫入數據
cellStyle = Getcellstyle(m_workbook, StyleXlsEnum.Default);
for (int i = 0; i < dt.Rows.Count; i++)
{
//跳過前兩行,第一行為標題,第二行為列名
IRow row = m_sheet.CreateRow(i + 2);
row.Height = 70 * 20;
ICell cell = row.CreateCell(0);
for (int j = 0; j < dt.Columns.Count; j++)
{
if (dt.Columns[j].ColumnName == "圖片")
{
cell = row.CreateCell(j);
cell.CellStyle = cellStyle;
saveFileName= Path.GetDirectoryName(saveFileName);
//將圖片文件讀入一個字符串
byte[] bytess = System.IO.File.ReadAllBytes(dt.Rows[i]["圖片"].ToString());
int pictureIdx = m_workbook.AddPicture(bytess, PictureType.JPEG);
HSSFPatriarch patriarch = (HSSFPatriarch)m_sheet.CreateDrawingPatriarch();
//前四個參數(dx1,dy1,dx2,dy2)為圖片在單元格的邊距
//col1,col2表示圖片插在col1和col2之間的單元格,索引從0開始
//row1,row2表示圖片插在第row1和row2之間的單元格,索引從1開始
// 參數的解析: HSSFClientAnchor(int dx1,int dy1,int dx2,int dy2,int col1,int row1,int col2,int row2)
//dx1:圖片左邊相對excel格的位置(x偏移) 范圍值為:0~1023;即輸100 偏移的位置大概是相對於整個單元格的寬度的100除以1023大概是10分之一
//dy1:圖片上方相對excel格的位置(y偏移) 范圍值為:0~256 原理同上。
//dx2:圖片右邊相對excel格的位置(x偏移) 范圍值為:0~1023; 原理同上。
//dy2:圖片下方相對excel格的位置(y偏移) 范圍值為:0~256 原理同上。
//col1和row1 :圖片左上角的位置,以excel單元格為參考,比喻這兩個值為(1,1),那么圖片左上角的位置就是excel表(1,1)單元格的右下角的點(A,1)右下角的點。
//col2和row2:圖片右下角的位置,以excel單元格為參考,比喻這兩個值為(2,2),那么圖片右下角的位置就是excel表(2,2)單元格的右下角的點(B,2)右下角的點。
HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, 8, i+2, 7, i + 3);
//把圖片插到相應的位置
HSSFPicture pict = (HSSFPicture)patriarch.CreatePicture(anchor, pictureIdx);
}
else
{
cell = row.CreateCell(j);
cell.SetCellValue(dt.Rows[i][j].ToString());
cell.CellStyle = cellStyle;
}
}
}
#endregion
//創建一個 IO 流
MemoryStream ms = new MemoryStream();
//寫入到流
m_workbook.Write(ms);
//轉換為字節數組
byte[] bytes = ms.ToArray();
//保存為Excel文件
using (FileStream fs = new FileStream(saveFileName, FileMode.Create, FileAccess.Write))
{
fs.Write(bytes, 0, bytes.Length);
fs.Flush();
}
//釋放資源
bytes = null;
ms.Close();
ms.Dispose();
m_workbook.Close();
m_sheet = null;
m_workbook = null;
m_cellStyle = null;
m_dataStyle = null;
m_font = null;
m_font12 = null;
m_font16 = null;
return true;
}
catch (Exception e)
{
Console.WriteLine(e);
return false;
}
}
private ICellStyle Getcellstyle(IWorkbook wb, StyleXlsEnum style)
{
try
{
//CreateFont()不能頻繁創建,會導致打開EXCEL表的時候報如下錯誤:
//此文件中的某些文本格式可能已經更改,因為它已經超出最多允許的字體數。
if (m_font16 == null)
{
m_font16 = wb.CreateFont();
m_font16.FontHeightInPoints = 16;
m_font16.FontName = "微軟雅黑";
m_font16.Boldweight = (short)FontBoldWeight.Bold;
}
if (m_font12 == null)
{
m_font12 = wb.CreateFont();
m_font12.FontHeightInPoints = 12;
m_font12.FontName = "微軟雅黑";
m_font12.Boldweight = (short)FontBoldWeight.Bold;
}
if (m_font == null)
{
m_font = wb.CreateFont();
m_font.FontName = "微軟雅黑";
}
m_cellStyle = wb.CreateCellStyle();
//邊框
m_cellStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.Medium;
m_cellStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.Medium;
m_cellStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.Medium;
m_cellStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.Medium;
//邊框顏色
//m_cellStyle.BottomBorderColor = HSSFColor.OliveGreen.Blue.Index;
//m_cellStyle.TopBorderColor = HSSFColor.OliveGreen.Blue.Index;
//背景圖形
//m_cellStyle.FillForegroundColor = HSSFColor.White.Index;
//m_cellStyle.FillBackgroundColor = HSSFColor.Blue.Index;
//水平對齊
m_cellStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
//垂直對齊
m_cellStyle.VerticalAlignment = VerticalAlignment.Center;
//自動換行
m_cellStyle.WrapText = false;
//縮進
//cellStyle.Indention = 0;
//}
//創建格式
if (m_dataStyle == null)
{
m_dataStyle = wb.CreateDataFormat();
}
//上面基本都是設共公的設置
//下面列出了常用的字段類型
switch (style)
{
case StyleXlsEnum.Head:
//cellStyle.FillPattern = FillPatternType.LEAST_DOTS;
//設置為文本格式,也可以為 text,即 dataFormat.GetFormat("text");
m_cellStyle.DataFormat = m_dataStyle.GetFormat("@");
m_cellStyle.SetFont(m_font16);
break;
case StyleXlsEnum.ColumnHead:
m_cellStyle.DataFormat = m_dataStyle.GetFormat("@");
m_cellStyle.SetFont(m_font12);
break;
case StyleXlsEnum.Default:
m_cellStyle.SetFont(m_font);
break;
}
return m_cellStyle;
}
catch
{
return m_cellStyle;
}
}