C# NPOI導出Excel以及動態設置列寬


通過NPOI將DataTable導出成Excel時,每列內容長度不一,統一設置寬度當然不太合理了,所以研究了下動態設置列寬。
首先根據表頭內容長度計算列寬,並將每列的列寬存於Dictionary<int, int>中,分別為每列序號和每列寬度。
然后在循環每行信息對每列內容賦值時,計算內容對應列寬,如超過表頭的寬度則替換Dictionary中的寬度值,注意Excel限制最大寬度為15000,超出則指定為15000。
注:內容自動換行后,行高會被撐開,項目導出格式需要,所以下面代碼中固定了行高,可根據需求自行判斷是否需要固定行高。

/// <summary>
/// Datable導出成Excel
/// </summary>
/// <param name="dt"></param>
/// <param name="file">導出路徑(包括文件名與擴展名)</param>
public static void TableToExcel(DataTable dt, string file)
{
    IWorkbook workbook;
    string fileExt = Path.GetExtension(file).ToLower();
    if (fileExt == ".xlsx")
    {
        workbook = new XSSFWorkbook();
    }
    else if (fileExt == ".xls")
    {
        workbook = new HSSFWorkbook();
    }
    else
    {
        return;
    }
            
    // 標題及內容單元格樣式
    var headCellStyle = CreateCellStyle(workbook, true);
    var contentCellStyle = CreateCellStyle(workbook, false);

    // 每列列寬字典
    var dic = new Dictionary<int, int>();

    ISheet sheet = string.IsNullOrEmpty(dt.TableName) ? workbook.CreateSheet("Sheet1") : workbook.CreateSheet(dt.TableName);

    //表頭  
    IRow row = sheet.CreateRow(0);
    for (int i = 0; i < dt.Columns.Count; i++)
    {
        ICell cell = row.CreateCell(i);
        cell.SetCellValue(dt.Columns[i].ColumnName);
        cell.CellStyle = headCellStyle;
        dic.Add(i, Encoding.Default.GetBytes(cell.StringCellValue).Length * 256 + 200);
    }

    //數據  
    for (int i = 0; i < dt.Rows.Count; i++)
    {
        IRow row1 = sheet.CreateRow(i + 1);

        // 行高,避免自動換行的內容將行高撐開
        row1.HeightInPoints = 20f;

        for (int j = 0; j < dt.Columns.Count; j++)
        {
            ICell cell = row1.CreateCell(j);
            cell.SetCellValue(dt.Rows[i][j].ToString());
            cell.CellStyle = contentCellStyle;
            int length = Encoding.Default.GetBytes(cell.StringCellValue).Length * 256 + 200;
            length = length > 15000 ? 15000 : length;

            // 若比已存在列寬更寬則替換,Excel限制最大寬度為15000
            if (dic[j] < length)
            {
                dic[j] = length;
            }
        }
    }

    for (int i = 0; i < dt.Columns.Count; i++)
    {
        sheet.SetColumnWidth(i, dic[i]);
    }

    //轉為字節數組  
    MemoryStream stream = new MemoryStream();
    workbook.Write(stream);
    var buf = stream.ToArray();

    //保存為Excel文件  
    using (FileStream fs = new FileStream(file, FileMode.Create, FileAccess.Write))
    {
        fs.Write(buf, 0, buf.Length);
        fs.Flush();
    }
}

/// <summary>
/// 單元格樣式
/// </summary>
/// <param name="workbook"></param>
/// <param name="isHead"></param>
/// <returns></returns>
private static ICellStyle CreateCellStyle(IWorkbook workbook, bool isHead)
{
    var cellStyle = workbook.CreateCellStyle();

    var font = workbook.CreateFont();
    font.IsBold = isHead; // 粗體  
    cellStyle.SetFont(font);
    if (isHead)
    {
        cellStyle.Alignment = HorizontalAlignment.Center; // 水平居中  
        cellStyle.VerticalAlignment = VerticalAlignment.Center; // 垂直居中  
    }
    cellStyle.BorderTop = BorderStyle.Thin;
    cellStyle.BorderBottom = BorderStyle.Thin;
    cellStyle.BorderLeft = BorderStyle.Thin;
    cellStyle.BorderRight = BorderStyle.Thin;
    cellStyle.WrapText = true;//內容自動換行,避免存在換行符的內容合並成單行

    return cellStyle;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM