写C#已经有一段时间,也练习了不少把程式模组化的设计方式,今天来分享一段最近写的,用NPOI来把DataSet物件转出单个Excel的方法,目前适用在Windows Form的画面使用,这是从个人使用的模组内挖出来的,由于程式内都已经固特意写好注解,就把整段贴上来吧。

using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.SS.Formula.Functions;
using Microsoft.IdentityModel.Tokens;
using System.Data;
using System.Reflection;
using System.Collections;
using System.ComponentModel.DataAnnotations;

namespace Modules
{
    public class Npoi
    {
        public string ExpFilename = "ExcelExport" + DateTime.Now.ToString("-yyMMdd_HHmm")+".xlsx";

        public Npoi()
        {

        }
        
	/// <summary>
	/// 将资料设定为资料表集合后 转出成Excel档案
	/// </summary>
	/// <param name="Ds">资料表的集合</param>
	/// <param name="filename">档案名称</param>
	/// <param name="Args">活页簿参数 </param>
	/// 假设 Ds.Tables 资料表数量 n
	///     Args 参数数量 0   : 以档案名称扩充 1.活页簿名称 2.标题
	///     Args 参数数量 n   : 以单一参数扩充 1.活页簿名称 2.标题 
	///     Args 参数数量 n*2 : 以参数对应 1.活页簿名称 2.标题 3.次标题(由标题扩充)
	///     Args 参数数量 n*3 : 以参数对应 1.活页簿名称 2.标题 3.次标题
	/// <returns>
	/// 资料表为空或零时 回应 -1 / 其馀则 回应 资料表数量 n 
	/// </returns>
	public int ExportExcelFile(DataSet Ds, string filename, string[] Args)
	{
    	if (!filename.IsNullOrEmpty())
        	ExpFilename = filename + DateTime.Now.ToString("-yyMMdd_HHmm") + ".xlsx";

	
    	if (Ds.Tables.Count == 0)
        	return -1;

	
    	int ArgTbCt = Args.Length / Ds.Tables.Count;
    	DateTime progTime = DateTime.Now;

	
    	// 建立试算表
    	XSSFWorkbook xSSFWorkbook = new XSSFWorkbook();
    	ICellStyle cellStyle = xSSFWorkbook.CreateCellStyle();  //首先建单元格格式
    	// 引用格式建立物件
    	XSSFDataFormat ft = (XSSFDataFormat)xSSFWorkbook.CreateDataFormat();

	
    	// 粗体字设定
    	XSSFFont f_bold = (XSSFFont)xSSFWorkbook.CreateFont();
    	f_bold.IsBold = true;
    
	
    	// 数字格式
    	XSSFCellStyle st_Num = (XSSFCellStyle)xSSFWorkbook.CreateCellStyle();
    	st_Num.DataFormat = ft.GetFormat("###,##0");

	
    	// 置中格式
    	XSSFCellStyle st_Cen = (XSSFCellStyle)xSSFWorkbook.CreateCellStyle();
    	st_Cen.Alignment = HorizontalAlignment.Center;
    	st_Cen.VerticalAlignment = VerticalAlignment.Center;

	
    	// 粗体字
    	XSSFCellStyle f_b = (XSSFCellStyle)xSSFWorkbook.CreateCellStyle();
    	f_b.SetFont(f_bold);

	
    	// 置中粗体格式
    	XSSFCellStyle st_f_b_Cen = (XSSFCellStyle)xSSFWorkbook.CreateCellStyle();
    	st_f_b_Cen.Alignment = HorizontalAlignment.Center;
    	st_f_b_Cen.VerticalAlignment = VerticalAlignment.Center;
    	st_f_b_Cen.SetFont(f_bold);

	
    	//粗体的数字
    	XSSFCellStyle st_N_f_B = (XSSFCellStyle)xSSFWorkbook.CreateCellStyle();
    	st_N_f_B.SetFont(f_bold);
    	st_N_f_B.DataFormat = ft.GetFormat("###,##0");

	
    	// 处理档案名称与活页簿名称
    	for (int i = 0; i < Ds.Tables.Count; i++)
    	{
        	DataTable Dt = Ds.Tables[i];
        	string sheet_name = "", sheet_title = "", sheet_subtitle = "";

	
        	// 侦测 字串阵列 / 资料表
        	switch (ArgTbCt)
        	{
            	// 一样多
            	case 1:
                	sheet_name = Args[i] + i.ToString("_00");
                	sheet_title = Args[i];
                	sheet_subtitle = "";
                	break;

	
            	// 两倍
            	case 2:
                	sheet_name = Args[i * ArgTbCt] + i.ToString("_00");
                	sheet_title = Args[i * ArgTbCt + 1];
                	sheet_subtitle = Args[i * ArgTbCt + 1];
                	break;

	
            	case 3:
                	sheet_name = Args[i * ArgTbCt] + i.ToString("_00");
                	sheet_title = Args[i * ArgTbCt + 1];
                	sheet_subtitle = Args[i * ArgTbCt + 2];
                	break;

	
            	// 为零时
            	default:
                	sheet_name = ExpFilename.Replace(".xlsx", "") + i.ToString("_00");
                	sheet_title = ExpFilename.Replace(".xlsx", "") + i.ToString("_00") + "_sheet";
                	sheet_subtitle = "";
                	break;
        	}
        	int c_ct = Dt.Columns.Count;

	
        	// 建立工作表物件
        	ISheet sheet = xSSFWorkbook.CreateSheet(sheet_name);

	
        	// 第0列
        	IRow rows = sheet.CreateRow(0);
        	rows.CreateCell(0).SetCellValue(sheet_title);
        	sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, c_ct - 1));
        	sheet.GetRow(0).GetCell(0).CellStyle = st_f_b_Cen;

	
        	// 第1列
        	rows = sheet.CreateRow(1);
        	rows.CreateCell(0).SetCellValue(sheet_subtitle);
        	sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(1, 1, 0, c_ct - 1));
        	sheet.GetRow(1).GetCell(0).CellStyle = st_Cen;

	
        	// 自第三列开始 向下写 先写入栏位名称
        	rows = sheet.CreateRow(3);
        	for (int j = 0; j < Dt.Columns.Count; j++)
        	{
            	rows.CreateCell(j).SetCellValue(Dt.Columns[j].ColumnName);
            	sheet.GetRow(3).GetCell(j).CellStyle = f_b;
        	}

	
        	// 使用双回圈自第四列往下写入各栏位
        	int m = 0;
        	for (int j = 0; j < Dt.Rows.Count; j++)
        	{
            	rows = sheet.CreateRow(j + 4);
            	for (int k = 0; k < Dt.Columns.Count; k++)
            	{
                	//判断内容是数字或文字 指定不同写入方法
                	if ( IsNumType(Dt.Columns[k].DataType) )
                	{
                    	rows.CreateCell(k).SetCellValue(Convert.ToDouble(Dt.Rows[j][k].ToString()!.Replace("&nbsp;", "")));
                	}
                	else
                	{
                    	rows.CreateCell(k).SetCellValue(Dt.Rows[j][k].ToString()!.Replace("&nbsp;", ""));
                	}
                	m = j + 5;
            	}
        	}

	
        	TimeSpan ts = DateTime.Now - progTime;
        	rows.CreateCell(Dt.Columns.Count).SetCellValue(ts.Milliseconds);

	
    	}

	
    	FileStream streamWriter = new FileStream(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\" + ExpFilename, FileMode.Create, FileAccess.ReadWrite);
    	// 把活页簿物件写入档案
    	xSSFWorkbook.Write(streamWriter);

	
    	streamWriter.Close();
    	streamWriter.Dispose();

	
    	return Ds.Tables.Count;
	}

	
	private bool IsNumType(Type type)
	{
    	bool IsNum = true;

	
    	if (type == typeof(String)) { IsNum = false; }
    	if (type == typeof(TimeSpan)) { IsNum = false; }

	
    	return IsNum;
	}

	
	/// <summary>
	/// 送入物件的类别是否为数字的判定
	/// </summary>
	/// <param name="sender"></param>
	/// <returns>数字为真,非数字返回否。</returns>
	private bool IsNum(object sender)
	{
    	bool IsNum = false;

	
    	IsNum = Decimal.TryParse((string)sender, out decimal tryit);

	
    	return IsNum;
	}
  }
}
iT邦帮忙 个人帐号:Kw6732