You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
274 lines
11 KiB
274 lines
11 KiB
using NPOI.HSSF.Util;
|
|
using NPOI.SS.UserModel;
|
|
using NPOI.SS.Util;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
|
|
namespace TeacherExt.Controllers
|
|
{
|
|
public static class NPOIHelper
|
|
{
|
|
public static ICell SetType(this ICell cell, CellType type)
|
|
{
|
|
cell.SetCellType(type);
|
|
return cell;
|
|
}
|
|
|
|
public static ICell SetStyle(this ICell cell, ICellStyle style)
|
|
{
|
|
cell.CellStyle = style;
|
|
return cell;
|
|
}
|
|
|
|
public static ICell SetCell(this IRow row,int col, ICellStyle style,object value,bool? flag=null,string kind=null)
|
|
{
|
|
var cell = row.GetCell(col) ?? row.CreateCell(col);
|
|
cell.SetStyle(style);
|
|
if(!flag.HasValue||flag.Value)
|
|
{
|
|
if (value != null)
|
|
{
|
|
if (value.GetType().UnderlyingSystemType == typeof(int))
|
|
{
|
|
cell.SetCellType(CellType.Numeric);
|
|
cell.SetCellValue((value as int?).Value);
|
|
}
|
|
else if (value.GetType().UnderlyingSystemType == typeof(DateTime))
|
|
{
|
|
cell.SetCellType(CellType.String);
|
|
cell.SetCellValue((value as DateTime?).Value.ToString("yyyy-MM"));
|
|
}
|
|
else
|
|
{
|
|
cell.SetCellType(CellType.String);
|
|
cell.SetCellValue(value as string);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cell.SetCellType(CellType.String);
|
|
cell.SetCellValue("无");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cell.SetCellType(CellType.String);
|
|
cell.SetCellValue("无");
|
|
}
|
|
return cell;
|
|
}
|
|
public static IRow Order(this IRow row, int order)
|
|
{
|
|
return row;
|
|
}
|
|
public static IRow Export(this IRow row, string rawCol, List<string> allExportHeaders, Expression<Func<dynamic>> property)
|
|
{
|
|
var member = ((property.Body as UnaryExpression)?.Operand as MemberExpression) ?? (property.Body as MemberExpression);
|
|
var excelHeader = member?.Member?.GetCustomAttribute<ExcelHeaderAttribute>()?.Header;
|
|
if (allExportHeaders!=null&& property != null&&!string.IsNullOrEmpty(excelHeader)&&!allExportHeaders.Contains(excelHeader))
|
|
{
|
|
return null;
|
|
}
|
|
return row;
|
|
}
|
|
|
|
public static ICellStyle CreateStyle(ISheet sheet, short? backgroundColor = null, double? fontSize = null, short? fontColor = null, bool isBold = false, string fontName = null, bool? textWrap = null)
|
|
{
|
|
var style = sheet.Workbook.CreateCellStyle();
|
|
if (backgroundColor.HasValue)
|
|
{
|
|
style.FillPattern = FillPattern.SolidForeground;
|
|
style.FillForegroundColor = backgroundColor.Value;
|
|
}
|
|
var font = sheet.Workbook.CreateFont();
|
|
if (!string.IsNullOrEmpty(fontName))
|
|
{
|
|
font.FontName = fontName;
|
|
}
|
|
font.IsBold = isBold;
|
|
if (fontSize.HasValue)
|
|
{
|
|
font.FontHeightInPoints = fontSize.Value;
|
|
}
|
|
if (fontColor.HasValue)
|
|
{
|
|
font.Color = fontColor.Value;
|
|
}
|
|
if (textWrap.HasValue)
|
|
{
|
|
style.WrapText = textWrap.Value;
|
|
}
|
|
style.SetFont(font);
|
|
style.Alignment = HorizontalAlignment.Center;
|
|
style.VerticalAlignment = VerticalAlignment.Center;
|
|
style.BorderTop = BorderStyle.Thin;
|
|
style.BorderRight = BorderStyle.Thin;
|
|
style.BorderBottom = BorderStyle.Thin;
|
|
style.BorderLeft = BorderStyle.Thin;
|
|
return style;
|
|
}
|
|
|
|
public static CellRangeAddress GetRegion(ISheet sheet, ICell cell)
|
|
{
|
|
CellRangeAddress result = null;
|
|
if (cell.IsMergedCell)
|
|
{
|
|
foreach (var region in sheet.MergedRegions)
|
|
{
|
|
if (cell.RowIndex >= region.FirstRow && cell.RowIndex <= region.LastRow && cell.ColumnIndex >= region.FirstColumn && cell.ColumnIndex <= region.LastColumn)
|
|
{
|
|
result = region;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static void RemoveRegion(ISheet sheet, CellRangeAddress region)
|
|
{
|
|
for (int i = 0; i < sheet.NumMergedRegions; i++)
|
|
{
|
|
var item = sheet.GetMergedRegion(i);
|
|
if (item.FirstRow == region.FirstRow
|
|
&& item.LastRow == region.LastRow
|
|
&& item.FirstColumn == region.FirstColumn
|
|
&& item.LastColumn == region.LastColumn)
|
|
{
|
|
sheet.RemoveMergedRegion(i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void SetColWidth(int lastHeadNum, ISheet sheet)
|
|
{
|
|
for (int i = lastHeadNum; i < sheet.LastRowNum; i++)
|
|
{
|
|
var row = sheet.GetRow(i);
|
|
if (row != null)
|
|
{
|
|
for (int j = 0; j < row.LastCellNum; j++)
|
|
{
|
|
var cell = sheet.GetRow(i).GetCell(j);
|
|
if (cell != null)
|
|
{
|
|
if (i == lastHeadNum && string.IsNullOrEmpty(cell.StringCellValue))
|
|
{
|
|
for (int k = 0; k < lastHeadNum + 1; k++)
|
|
{
|
|
if (i - k >= 0)
|
|
{
|
|
var tempCell = sheet.GetRow(i - k).GetCell(j);
|
|
if (tempCell.StringCellValue != "")
|
|
{
|
|
cell = tempCell;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var length = ((cell.ToString().Split('\n').Select(o => Encoding.UTF8.GetBytes(o).Count()).Max()) + 1) * 256;
|
|
if (length > sheet.GetColumnWidth(j))
|
|
{
|
|
sheet.SetColumnWidth(j, length);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static List<string> CreateHader(ISheet sheet, Type modelType, List<string> includeHeaders)
|
|
{
|
|
var style = NPOIHelper.CreateStyle(sheet, backgroundColor: HSSFColor.PaleBlue.Index, fontSize: 11, fontColor: HSSFColor.White.Index, isBold: true, fontName: "黑体", textWrap: true);
|
|
var result = new List<string>();
|
|
var headers = modelType.GetProperties().Select(o => o.GetCustomAttribute<ExcelHeaderAttribute>()).Where(o => o != null).ToList();
|
|
var colIndex = 0;
|
|
foreach (var item in headers)
|
|
{
|
|
if (!includeHeaders.Any() || includeHeaders.Contains(item.Header))
|
|
{
|
|
result.Add(item.Header);
|
|
int i = 0;
|
|
foreach (var head in item.Headers)
|
|
{
|
|
for (int j = i; j < i + head.Value; j++)
|
|
{
|
|
var row = (sheet.GetRow(j) ?? sheet.CreateRow(j));
|
|
var cell = (row.GetCell(colIndex) ?? row.CreateCell(colIndex));
|
|
cell.SetStyle(style);
|
|
if (j == i)
|
|
{
|
|
cell.SetCellValue(head.Key);
|
|
}
|
|
}
|
|
if (head.Value > 1)
|
|
{
|
|
sheet.AddMergedRegion(new CellRangeAddress(i, i + head.Value - 1, colIndex, colIndex));
|
|
sheet.GetRow(i).GetCell(colIndex).SetStyle(style);
|
|
}
|
|
i = i + head.Value;
|
|
}
|
|
colIndex += 1;
|
|
}
|
|
}
|
|
for (int i = 0; i < sheet.LastRowNum; i++)
|
|
{
|
|
var row = sheet.GetRow(i);
|
|
for (int j = 0; j < row.LastCellNum; j++)
|
|
{
|
|
var cell = row.GetCell(j);
|
|
var cells = new List<ICell>() { cell };
|
|
if (cell != null && cell.StringCellValue != "")
|
|
{
|
|
var col = 1;
|
|
if (j + 1 < row.LastCellNum)
|
|
{
|
|
for (int k = j + 1; k < row.LastCellNum; k++)
|
|
{
|
|
var next = row.GetCell(k);
|
|
if (next == null || next.StringCellValue != cell.StringCellValue)
|
|
{
|
|
break;
|
|
}
|
|
next.SetCellValue("");
|
|
cells.Add(next);
|
|
col++;
|
|
}
|
|
}
|
|
if (col > 1)
|
|
{
|
|
if (!cell.IsMergedCell)
|
|
{
|
|
sheet.AddMergedRegion(new CellRangeAddress(i, i, j, j + col - 1));
|
|
}
|
|
else
|
|
{
|
|
var currentRegion = NPOIHelper.GetRegion(sheet, cell);
|
|
var rowEnd = currentRegion.LastRow;
|
|
foreach (var rcell in cells)
|
|
{
|
|
var region = NPOIHelper.GetRegion(sheet, rcell);
|
|
if (region != null)
|
|
{
|
|
NPOIHelper.RemoveRegion(sheet, region);
|
|
}
|
|
}
|
|
sheet.AddMergedRegion(new CellRangeAddress(i, rowEnd, j, j + col - 1));
|
|
}
|
|
}
|
|
j = j + col - 1;
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
}
|