@ -1,15 +1,24 @@
using System ;
using System.Collections.Generic ;
using System.ComponentModel.DataAnnotations ;
using System.Data ;
using System.IO ;
using System.Linq ;
using System.Linq.Dynamic.Core ;
using System.Text ;
using System.Threading.Tasks ;
using Google.Protobuf.Collections ;
using NPOI.HSSF.UserModel ;
using NPOI.OpenXmlFormats.Spreadsheet ;
using NPOI.SS.UserModel ;
using NPOI.SS.Util ;
using NPOI.XSSF.UserModel ;
using SqlSugar ;
using Tiobon.Core.Common ;
using Tiobon.Core.Common.DB ;
using Tiobon.Core.Common.DB.Dapper ;
using Tiobon.Core.Common.Extensions ;
using Tiobon.Core.Model.Models ;
namespace Tiobon.Core.DataAccess ;
/// <summary>
@ -98,4 +107,448 @@ public static class ReportHelper
}
# endregion
public static async Task < long > ExportExcel ( ISqlSugarClient Db , List < QueryExportColumn > tableColumn , DataTable dt )
{
string filepath = "" ;
//生成表格
try
{
IWorkbook fileWorkbook ;
bool IsHSSF = true ;
if ( Path . GetExtension ( filepath ) = = ".xls" )
{
IsHSSF = true ;
fileWorkbook = new HSSFWorkbook ( ) ;
}
else
{
IsHSSF = false ;
fileWorkbook = new XSSFWorkbook ( ) ;
}
int index = 0 ;
//创建Sheet;
ISheet sheet = fileWorkbook . CreateSheet ( "导入数据" ) ;
ISheet sheet2 = fileWorkbook . CreateSheet ( "下拉数据" ) ;
//隐藏下拉数据Sheet
//fileWorkbook.SetSheetHidden(fileWorkbook.GetSheetIndex("下拉数据"), SheetState.Hidden);
IRow erow_1 = sheet . CreateRow ( 0 ) ; //ID行
IRow erow_2 = sheet . CreateRow ( 1 ) ; //文本行
erow_1 . CreateCell ( 0 ) . SetCellValue ( "ExcelNums" ) ;
erow_2 . CreateCell ( 0 ) . SetCellValue ( "序号" ) ;
//必填颜色
var CellRed = fileWorkbook . CreateCellStyle ( ) ; // 创建单元格样式
IFont Font = fileWorkbook . CreateFont ( ) ; // 创建字体
Font . Color = IndexedColors . Red . Index ; // 选择字体颜色
CellRed . SetFont ( Font ) ; // 把字体赋给样式
erow_2 . GetCell ( 0 ) . CellStyle = CellRed ;
//文本类型
ICellStyle cellString = fileWorkbook . CreateCellStyle ( ) ;
IDataFormat cellFormat = fileWorkbook . CreateDataFormat ( ) ;
cellString . DataFormat = cellFormat . GetFormat ( "@" ) ;
//下拉数据列ID
int listColIndex = 0 ;
int ColNums = 0 ;
foreach ( var drow in tableColumn )
{
int SortNum = Convert . ToInt32 ( drow . sortNum ) ;
ICell cell = erow_1 . CreateCell ( SortNum ) ;
ICell cel2 = erow_2 . CreateCell ( SortNum ) ;
string field = drow . field ;
;
string label = drow . label ;
// 批注
string commentText = string . Empty ;
try
{
commentText = drow . commentText ;
}
catch ( Exception )
{
}
cell . SetCellValue ( field ) ;
cel2 . SetCellValue ( label ) ;
// 设置批注
if ( ! string . IsNullOrEmpty ( commentText ) )
{
cel2 . CellComment = GetComment ( sheet , null , ColNums , commentText ) ;
}
//是否必填
if ( drow . required = = "true" )
{
cel2 . CellStyle = CellRed ;
}
string dataSource = drow . dataSource ;
//是否下拉
if ( ! string . IsNullOrEmpty ( dataSource )
& & ! dataSource . StartsWith ( "OrgTreeWith" )
& & ! dataSource . StartsWith ( "StaffWith" )
)
{
List < DataSourceList > dataSourceLists = GetDataSourceLists ( Db , field , dataSource ) ;
//下拉数据行ID
int listRowIndex = 1 ;
//写入下拉值区域
IRow rowTitle = sheet2 . GetRow ( 0 ) ;
if ( rowTitle = = null )
rowTitle = sheet2 . CreateRow ( 0 ) ;
rowTitle . CreateCell ( listColIndex ) . SetCellValue ( label ) ;
foreach ( var data in dataSourceLists ) //将下拉列表中的数据循环赋给sheet页
{
IRow row = sheet2 . GetRow ( listRowIndex ) ;
if ( row = = null )
row = sheet2 . CreateRow ( listRowIndex ) ;
listRowIndex = listRowIndex + 1 ;
row . CreateCell ( listColIndex ) . SetCellValue ( data . name ) ;
}
// 定义一个名称,指向刚才创建的下拉项的区域:
var rangeName = field + "Range" ;
IName range = fileWorkbook . CreateName ( ) ;
string ABC = Other . Num2ABCletter ( ( listColIndex + 1 ) ) ;
//range.RefersToFormula = "下拉数据" + "!$"+ ABC + "$2:$"+ ABC + "$" + (listRowIndex == 0 ? 2 : listRowIndex);
//Excel 正常引用
string a1 = "下拉数据" + "!$" + ABC + "$2:$" + ABC + "$" + ( listRowIndex = = 0 ? 2 : listRowIndex ) ;
// Excel R1C1引用样式
string a2 = "下拉数据" + "!$R2C" + listColIndex . ToString ( ) + ":R" + listRowIndex . ToString ( ) + "C" + listColIndex . ToString ( ) ;
listColIndex = listColIndex + 1 ;
range . RefersToFormula = a1 ;
range . NameName = rangeName ;
//-----------------分割线以上是用来创建一个sheet页赋值,然后将sheet页中的内容定义成一个名称,后面用来当作数组传入方法的过程
CellRangeAddressList cellRegions = new CellRangeAddressList ( 1 , 6 5 5 3 5 , SortNum , SortNum ) ; //
DVConstraint constraint = DVConstraint . CreateFormulaListConstraint ( rangeName ) ;
//HSSFDataValidation dataValidate = new HSSFDataValidation(cellRegions, constraint);
//IDataValidationConstraint constraint;
IDataValidation dataValidate ;
if ( Path . GetExtension ( filepath ) = = ".xls" )
{
constraint = DVConstraint . CreateFormulaListConstraint ( rangeName ) ;
dataValidate = new HSSFDataValidation ( cellRegions , constraint ) ;
}
else
{
CT_DataValidation cdv = new CT_DataValidation ( ) ;
cdv . allowBlank = true ;
//constraint = CT_DataValidation
dataValidate = new XSSFDataValidation ( cellRegions , cdv ) ;
}
// 多选 ,自行输入不报错
if ( drow . elementType . ToString ( ) . LastIndexOf ( "multiple" ) = = - 1 )
{
dataValidate . CreateErrorBox ( "输入不合法" , "请输入或选择下拉列表中的值。" ) ;
dataValidate . ShowPromptBox = true ;
}
else
{
dataValidate . ShowErrorBox = false ;
}
sheet . AddValidationData ( dataValidate ) ;
}
//是否文本格式
if ( drow . dataType ! = "int"
& & drow . dataType ! = "decimal"
& & drow . dataType ! = "number"
)
{
sheet . SetDefaultColumnStyle ( ColNums , cellString ) ;
}
ColNums = ColNums + 1 ;
}
erow_1 . HeightInPoints = 1 ;
// 如果导出模板存在默认数据
//if (ds.Tables[1] != null && ds.Tables[1].Rows.Count > 0)
for ( int i = 0 ; i < dt . Rows . Count ; i + + )
{
IRow row1 = sheet . CreateRow ( i + 2 ) ;
for ( int j = 0 ; j < dt . Columns . Count ; j + + )
{
ICell cell = row1 . CreateCell ( j ) ;
cell . SetCellValue ( dt . Rows [ i ] [ j ] . ToString ( ) ) ;
}
}
////月排班维护写入下拉数据
//if (menuName == "F_SchedulePeriodSetup")
//{
// string listSql = @" select ParaDetailNo 日期类别编号,ParaDetailName 日期类别名称 from Ghrs_ParaDetail where ParaMasterNo = 'DateType' and IsEnable = 1;
// select ShiftNo 班次编号,ShiftName 班次名称 from Ghrb_Shift where IsEnable = 1;
// select ShiftGroupNo 班组编号,ShiftGroupName 班组名称 from Ghrb_ShiftGroup where IsEnable = 1; ";
// InsertExcelList(sheet2, listSql);
//}
//// 生成部门Sheet
//if (tableColumn.Rows.Cast<DataRow>().Any(x => x["dataSource"].ToString().StartsWith("OrgTreeWith")))
//{
// ISheet sheetDept = fileWorkbook.CreateSheet("部门数据");
// string listSql = @" select DeptNo 部门编号,DeptName 部门名称 from Ghro_Dept where IsEnable = 1 and convert(date,getdate()) between BeginDate and ISNULL(EndDate,'2099-12-31') ";
// InsertExcelList(sheetDept, listSql);
//}
// Sheet 更改列为自适应宽度
for ( int col = 0 ; col < = ColNums ; col + + )
{
try
{
sheet . AutoSizeColumn ( col ) ; //自适应宽度,但是其实还是比实际文本要宽
var columnWidth = sheet . GetColumnWidth ( col ) / 2 5 6 ; //获取当前列宽度
for ( int rowIndex = 1 ; rowIndex < = sheet . LastRowNum ; rowIndex + + )
{
IRow row = sheet . GetRow ( rowIndex ) ;
ICell cell = row . GetCell ( col ) ;
int contextLength = Encoding . UTF8 . GetBytes ( cell . ToString ( ) ) . Length ; //获取当前单元格的内容宽度
columnWidth = columnWidth < contextLength ? contextLength : columnWidth ;
}
sheet . SetColumnWidth ( col , columnWidth * 2 5 6 ) ; //
}
catch ( Exception )
{
}
}
// Sheet2 更改列为自适应宽度
//if (listColIndex > 0)
//{
// for (int col = 0; col <= listColIndex - 1; col++)
// {
// sheet2.AutoSizeColumn(col);//自适应宽度,但是其实还是比实际文本要宽
// int columnWidth = sheet2.GetColumnWidth(col) / 256;//获取当前列宽度
// for (int rowIndex = 1; rowIndex <= sheet2.LastRowNum; rowIndex++)
// {
// IRow row = sheet2.GetRow(rowIndex);
// ICell cell = row.GetCell(col);
// int contextLength = Encoding.UTF8.GetBytes(cell.ToString()).Length;//获取当前单元格的内容宽度
// columnWidth = columnWidth < contextLength ? contextLength : columnWidth;
// }
// sheet2.SetColumnWidth(col, columnWidth * 256);//
// }
//}
//转为字节数组
MemoryStream stream = new MemoryStream ( ) ;
fileWorkbook . Write ( stream ) ;
var buf = stream . ToArray ( ) ;
//保存为Excel文件
using ( FileStream fs = new FileStream ( filepath , FileMode . Create , FileAccess . Write ) )
{
fs . Write ( buf , 0 , buf . Length ) ;
fs . Flush ( ) ;
}
}
catch ( Exception ex )
{
}
return default ( long ) ;
}
/// <summary>
/// Excel字段下拉
/// </summary>
public class DataSourceList
{
public string field { get ; set ; }
public string id { get ; set ; }
public string no { get ; set ; }
public string name { get ; set ; }
} /// <summary>
/// 设置Excel批注
/// </summary>
/// <param name="sheet"> sheet</param>
/// <param name="comment"> comment </param>
/// <param name="cellnum"> 列 </param>
/// <param name="text">文本</param>
/// <returns></returns>
private static IComment GetComment ( ISheet sheet , IComment comment , int cellnum , string text )
{
IWorkbook workbook = sheet . Workbook ;
bool exportXlsx = workbook is XSSFWorkbook ;
if ( comment = = null )
{
IDrawing draw = sheet . CreateDrawingPatriarch ( ) ;
IClientAnchor clientAnchor = null ;
if ( exportXlsx )
{
clientAnchor = new XSSFClientAnchor ( 0 , 0 , 0 , 0 , cellnum , 0 , cellnum + 2 , 6 ) ;
}
else
{
clientAnchor = new HSSFClientAnchor ( 0 , 0 , 0 , 0 , cellnum , 0 , cellnum + 2 , 6 ) ;
}
comment = draw . CreateCellComment ( clientAnchor ) ;
}
IRichTextString richText = null ;
if ( exportXlsx )
{
richText = new XSSFRichTextString ( string . Format ( "{0}" , text ) ) ;
}
else
{
richText = new HSSFRichTextString ( string . Format ( "{0}" , text ) ) ;
}
//richText.ApplyFont(GetDefaultFont(workbook, true));// 设置批注中文本的字体
comment . String = richText ;
comment . Visible = false ;
comment . Author = "Tiobon" ;
return comment ;
}
/// <summary>
/// 获取数据下拉
/// </summary>
/// <param name="dataSource"></param>
/// <returns></returns>
public static List < DataSourceList > GetDataSourceLists ( ISqlSugarClient Db , string field , string dataSource )
{
List < DataSourceList > dataSourceList = new List < DataSourceList > ( ) ;
try
{
////Dept
//if (dataSource.StartsWith("OrgTreeWith"))
//{
//}
////Staff
//else if (dataSource.StartsWith("StaffWith"))
//{
//}
//else
{
string listSQL = string . Format ( @"exec[dbo].[PRI_ListValue] '{0}','GetEnableList','',1,63,'',9999,1,2" , dataSource ) ;
DataSet listds = Db . Ado . GetDataSetAll ( listSQL ) ;
if ( listds . Tables . Count > 3 )
{
DataTable listdt = new DataTable ( ) ;
listdt = listds . Tables [ 2 ] ;
foreach ( DataRow row in listdt . Rows )
{
DataSourceList _d ataSource = new DataSourceList ( ) ;
_d ataSource . field = field ;
try
{
_d ataSource . id = row [ "value" ] . ToString ( ) ;
_d ataSource . name = row [ "label" ] . ToString ( ) ;
}
catch ( Exception )
{
_d ataSource . id = row [ 0 ] . ToString ( ) ;
_d ataSource . name = row [ 1 ] . ToString ( ) ;
try
{
_d ataSource . name = _d ataSource . name + " " + row [ 2 ] . ToString ( ) ;
}
catch ( Exception )
{
}
}
dataSourceList . Add ( _d ataSource ) ;
}
}
}
}
catch ( Exception )
{
}
return dataSourceList ;
}
/// <summary>
///
/// </summary>
/// <param name="sheet"></param>
/// <param name="sql">需要写入的查询的SQL</param>
/// <param name="rows">开始行</param>
/// <param name="cols">开始列</param>
/// <returns></returns>
public static bool InsertExcelList ( ISqlSugarClient Db , ISheet sheet , string sql )
{
bool IsBool = false ;
DataSet ds = Db . Ado . GetDataSetAll ( sql ) ;
//写入下拉值区域
int cols = 0 ;
foreach ( DataTable dt in ds . Tables )
{
int col = 0 ;
//表头
IRow row = sheet . GetRow ( 0 ) ;
if ( row = = null )
row = sheet . CreateRow ( 0 ) ;
for ( int i = 0 ; i < dt . Columns . Count ; i + + )
{
ICell cell = row . CreateCell ( i + cols ) ;
cell . SetCellValue ( dt . Columns [ i ] . ColumnName ) ;
col + + ;
}
//数据
for ( int i = 0 ; i < dt . Rows . Count ; i + + )
{
IRow row1 = sheet . GetRow ( i + 1 ) ;
if ( row1 = = null )
row1 = sheet . CreateRow ( i + 1 ) ;
for ( int j = 0 ; j < dt . Columns . Count ; j + + )
{
ICell cell = row1 . CreateCell ( j + cols ) ;
cell . SetCellValue ( dt . Rows [ i ] [ j ] . ToString ( ) ) ;
}
}
cols = cols + col + 1 ;
}
return IsBool ;
}
#region 其他
public class Other
{
/// <summary>
/// 数字转ADC字母
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string Num2ABCletter ( [ Range ( 1 , 3 0 0 ) ] int value )
{
List < string > Level = new List < string >
{
"A" , "B" , "C" , "D" , "E" , "F" , "G" , "H" , "I" , "J" ,
"K" , "L" , "M" , "N" , "O" , "P" , "Q" , "R" , "S" , "T" ,
"U" , "V" , "W" , "X" , "Y" , "Z" ,
} ;
value = value - 1 ;
System . Text . ASCIIEncoding asciiEncoding = new System . Text . ASCIIEncoding ( ) ;
int remainder = value % 2 6 ; //余数
int front = ( value - remainder ) / 2 6 ; / /
if ( front = = 0 )
{
return Level [ remainder ] ;
}
else if ( front < 2 6 )
{
return Level [ front - 1 ] + Level [ remainder ] ;
}
else
{
return Num2ABCletter ( front ) + Level [ remainder ] ;
}
}
}
# endregion
}