iotgateway/WalkingTec.Mvvm/WalkingTec.Mvvm.Core/BaseTemplateVM.cs
2021-12-14 14:10:44 +08:00

346 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.IO;
using System.Linq;
using NPOI.HSSF.UserModel;
using NPOI.HSSF.Util;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
namespace WalkingTec.Mvvm.Core
{
public class BaseTemplateVM : BaseVM
{
#region
/// <summary>
/// 下载模板显示名称
/// </summary>
public string FileDisplayName { get; set; }
/// <summary>
/// 是否验证模板类型当其他系统模板导入到某模块时可设置为False
/// </summary>
public bool ValidityTemplateType { get; set; }
/// <summary>
/// 需要导出的数据
/// </summary>
public DataTable TemplateDataTable { get; set; }
/// <summary>
/// 下载模版页面参数
/// </summary>
public Dictionary<string, string> Parms { get; set; }
/// <summary>
/// Excel索引
/// </summary>
public long ExcelIndex { get; set; }
#endregion
#region
public BaseTemplateVM()
{
ValidityTemplateType = true;
Parms = new Dictionary<string, string>();
var propetys = this.GetType().GetFields().Where(x => x.FieldType == typeof(ExcelPropety)).ToList();
for (int porpetyIndex = 0; porpetyIndex < propetys.Count(); porpetyIndex++)
{
ExcelPropety excelPropety = (ExcelPropety)propetys[porpetyIndex].GetValue(this);
if (propetys[porpetyIndex].GetCustomAttributes(typeof(DisplayAttribute), false).Length == 0)
{
excelPropety.ColumnName = excelPropety.FieldDisplayName;
}
else
{
excelPropety.ColumnName = propetys[porpetyIndex].GetPropertyDisplayName();
}
}
}
#endregion
#region Excel属性数据
/// <summary>
/// 初始化Excel属性数据 包括动态列,列表中的下拉选项
/// </summary>
public virtual void InitExcelData()
{
}
public virtual void InitCustomFormat()
{
}
#endregion
#region
/// <summary>
/// 初始化模版数据
/// </summary>
public virtual void SetTemplateDataValus()
{
}
#endregion
#region
/// <summary>
/// 生成模板
/// </summary>
/// <param name="displayName">文件名</param>
/// <returns>生成的模版文件</returns>
public byte[] GenerateTemplate(out string displayName)
{
//设置导出的文件名称
string SheetName = !string.IsNullOrEmpty(FileDisplayName) ? FileDisplayName : this.GetType().Name;
displayName = SheetName + "_" + DateTime.Now.ToString("yyyy-MM-dd") + "_" + DateTime.Now.ToString("hh^mm^ss") + ".xlsx";
//1.声明Excel文档
IWorkbook workbook = new XSSFWorkbook();
//加载初始化数据和下拉菜单数据,可重载
InitExcelData();
//设置TemplateDataTable的各列的类型
CreateDataTable();
//设置初始化数据到DataTable中
SetTemplateDataValus();
//2.设置workbook的sheet页
ISheet sheet = workbook.CreateSheet();
workbook.SetSheetName(0, SheetName);
//3.设置Sheet页的Row
IRow row = sheet.CreateRow(0);
row.HeightInPoints = 20;
ISheet enumSheet = workbook.CreateSheet();
IRow enumSheetRow1 = enumSheet.CreateRow(0);
enumSheetRow1.CreateCell(0).SetCellValue(CoreProgram._localizer?["Sys.Yes"]);
enumSheetRow1.CreateCell(1).SetCellValue(CoreProgram._localizer?["Sys.No"]);
enumSheetRow1.CreateCell(2).SetCellValue(this.GetType().Name); //为模板添加标记,必要时可添加版本号
ISheet dataSheet = workbook.CreateSheet();
#region excel模板列头
//默认灰色
var headerStyle = GetCellStyle(workbook);
headerStyle.IsLocked = true;
//黄色
var yellowStyle = GetCellStyle(workbook, BackgroudColorEnum.Yellow);
yellowStyle.IsLocked = true;
//红色
var redStyle = GetCellStyle(workbook, BackgroudColorEnum.Red);
redStyle.IsLocked = true;
//取得所有ExcelPropety
var propetys = this.GetType().GetFields().Where(x => x.FieldType == typeof(ExcelPropety)).ToList();
//设置列的索引
int _currentColunmIndex = 0;
//设置Excel是否需要保护默认不保护
bool IsProtect = false;
//循环类的属性,赋值给列
for (int porpetyIndex = 0; porpetyIndex < propetys.Count(); porpetyIndex++)
{
//依次获取属性字段
ExcelPropety excelPropety = (ExcelPropety)propetys[porpetyIndex].GetValue(this);
ColumnDataType dateType = (excelPropety.DataType == ColumnDataType.DateTime || excelPropety.DataType == ColumnDataType.Date) ? ColumnDataType.Text : excelPropety.DataType; //日期类型默认设置成Text类型,在赋值时会进行日期验证
//设置是否保护Excel
if (excelPropety.ReadOnly)
{
IsProtect = true;
}
//给必填项加星号
string colName = excelPropety.IsNullAble ? excelPropety.ColumnName : excelPropety.ColumnName + "*";
row.CreateCell(_currentColunmIndex).SetCellValue(colName);
//修改列头样式
switch (excelPropety.BackgroudColor)
{
case BackgroudColorEnum.Yellow:
row.Cells[_currentColunmIndex].CellStyle = yellowStyle;
break;
case BackgroudColorEnum.Red:
row.Cells[_currentColunmIndex].CellStyle = redStyle;
break;
default:
row.Cells[_currentColunmIndex].CellStyle = headerStyle;
break;
}
var dataStyle = workbook.CreateCellStyle();
var dataFormat = workbook.CreateDataFormat();
if (dateType == ColumnDataType.Dynamic)
{
int dynamicColCount = excelPropety.DynamicColumns.Count();
for (int dynamicColIndex = 0; dynamicColIndex < dynamicColCount; dynamicColIndex++)
{
var dynamicCol = excelPropety.DynamicColumns.ToList()[dynamicColIndex];
string dynamicColName = excelPropety.IsNullAble ? dynamicCol.ColumnName : dynamicCol.ColumnName + "*";
row.CreateCell(_currentColunmIndex).SetCellValue(dynamicColName);
row.Cells[_currentColunmIndex].CellStyle = headerStyle;
if (dynamicCol.ReadOnly)
{
IsProtect = true;
}
//设定列宽
if (excelPropety.CharCount > 0)
{
sheet.SetColumnWidth(_currentColunmIndex, excelPropety.CharCount * 256);
dataStyle.WrapText = true;
}
else
{
sheet.AutoSizeColumn(_currentColunmIndex);
}
//设置单元格样式及数据类型
dataStyle.IsLocked = excelPropety.ReadOnly;
dynamicCol.SetColumnFormat(dynamicCol.DataType, _currentColunmIndex, sheet, dataSheet, dataStyle, dataFormat);
_currentColunmIndex++;
}
}
else
{
//设定列宽
if (excelPropety.CharCount > 0)
{
sheet.SetColumnWidth(_currentColunmIndex, excelPropety.CharCount * 256);
dataStyle.WrapText = true;
}
else
{
sheet.AutoSizeColumn(_currentColunmIndex);
}
//设置是否锁定
dataStyle.IsLocked = excelPropety.ReadOnly;
//设置单元格样式及数据类型
excelPropety.SetColumnFormat(dateType, _currentColunmIndex, sheet, dataSheet, dataStyle, dataFormat);
_currentColunmIndex++;
}
}
#endregion
#region
if (TemplateDataTable.Rows.Count > 0)
{
for (int i = 0; i < TemplateDataTable.Rows.Count; i++)
{
DataRow tableRow = TemplateDataTable.Rows[i];
IRow dataRow = sheet.CreateRow(1 + i);
for (int porpetyIndex = 0; porpetyIndex < propetys.Count(); porpetyIndex++)
{
string colName = propetys[porpetyIndex].Name;
tableRow[colName].ToString();
dataRow.CreateCell(porpetyIndex).SetCellValue(tableRow[colName].ToString());
}
}
}
#endregion
//冻结行
sheet.CreateFreezePane(0, 1, 0, 1);
//锁定excel
if (IsProtect)
{
sheet.ProtectSheet("password");
}
//隐藏前2个Sheet
workbook.SetSheetHidden(1, SheetState.Hidden);
workbook.SetSheetHidden(2, SheetState.Hidden);
//返回byte数组
MemoryStream ms = new MemoryStream();
workbook.Write(ms);
return ms.ToArray();
}
#endregion
#region
private static ICellStyle GetCellStyle(IWorkbook workbook, BackgroudColorEnum backgroudColor = BackgroudColorEnum.Grey)
{
var headerStyle = workbook.CreateCellStyle();
//设定表头样式
headerStyle.BorderBottom = BorderStyle.Thin;
headerStyle.BorderLeft = BorderStyle.Thin;
headerStyle.BorderRight = BorderStyle.Thin;
headerStyle.BorderTop = BorderStyle.Thin;
//用灰色填充背景
short headerbg;
switch (backgroudColor)
{
case BackgroudColorEnum.Grey:
headerbg = HSSFColor.LightBlue.Index;
break;
case BackgroudColorEnum.Yellow:
headerbg = HSSFColor.LightYellow.Index;
break;
case BackgroudColorEnum.Red:
headerbg = HSSFColor.Pink.Index;
break;
default:
headerbg = HSSFColor.Pink.Index;
break;
}
headerStyle.FillForegroundColor = headerbg;
headerStyle.FillPattern = FillPattern.SolidForeground;
headerStyle.FillBackgroundColor = headerbg;
headerStyle.Alignment = HorizontalAlignment.Center;
return headerStyle;
}
#endregion
#region DataTable()
private void CreateDataTable()
{
TemplateDataTable = new DataTable();
var propetys = this.GetType().GetFields().Where(x => x.FieldType == typeof(ExcelPropety)).ToList();
foreach (var p in propetys)
{
ExcelPropety excelPropety = (ExcelPropety)p.GetValue(this);
ColumnDataType dateType = excelPropety.DataType;
switch (dateType)
{
case ColumnDataType.Bool:
TemplateDataTable.Columns.Add(p.Name, typeof(bool));
break;
case ColumnDataType.Date:
TemplateDataTable.Columns.Add(p.Name, typeof(string));
break;
case ColumnDataType.Number:
TemplateDataTable.Columns.Add(p.Name, typeof(int));
break;
case ColumnDataType.Text:
TemplateDataTable.Columns.Add(p.Name, typeof(string));
break;
case ColumnDataType.Float:
TemplateDataTable.Columns.Add(p.Name, typeof(decimal));
break;
default:
TemplateDataTable.Columns.Add(p.Name, typeof(string));
break;
}
}
}
#endregion
}
}