팡이네

ClosedXML 사용

C#2017. 5. 17. 15:42

* AddWorksheet() 새로운 워크시트를 만든다.

public IXLWorksheet AddWorksheet(XLWorkbook wb, string sheetName)
{
	var ws = wb.AddWorksheet(sheetName);
	ws.Style.Font.SetFontName("맑은 고딕");	//기본글꼴
	ws.Style.Font.SetFontSize(10);			//기본글꼴크기
	ws.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center;	//세로맞춤: 가운데

	return ws;
}

* GetExcelColumn() 지정한 컬럼의 엑셀 컬럼문자를 가져온다.

public string GetExcelColumn(int columnIndex)
	{
		var colString = "";

		if (columnIndex > 26)
		{
			var surplus = columnIndex % 26; if (surplus == 0) surplus = 26;
			var quota = (columnIndex - surplus) / 26;

			//3글자 컬럼명
			if (quota > 26)
			{
				var surplus2 = quota % 26;
				var quota2 = (quota - surplus2) / 26;

				colString = string.Format("{0}{1}{2}", Convert.ToChar(64 + quota2), Convert.ToChar(64 + surplus2), Convert.ToChar(64 + surplus));
			}
			//2글자 컬럼명
			else
			{
				colString = string.Format("{0}{1}", Convert.ToChar(64 + quota), Convert.ToChar(64 + surplus));
			}
		}
		else
		{
			colString = string.Format("{0}", Convert.ToChar(64 + columnIndex));
		}

		return colString;
	}

* AddExcelCell() 지정한 셀에 숫자값을 표시한다.

public IXLCell AddExcelCell(IXLWorksheet ws, int row, int col, int value, string bgColor
						, bool bold, XLAlignmentHorizontalValues hAlign)
{
	var cell = ws.Cell(row, col);
	cell.SetValue(value);
	cell.DataType = XLCellValues.Number;
	cell.Style.NumberFormat.Format = "#,##0;(#,##0);-";
	cell.Style.Alignment.Horizontal = hAlign;
	cell.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center;
	cell.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
	if (bold) cell.Style.Font.Bold = true;
	if (!string.IsNullOrEmpty(bgColor)) cell.Style.Fill.BackgroundColor = XLColor.FromHtml(bgColor);

	return cell;
}

* AddExcelCell() 지정한 셀에 문자열을 표시한다.

public IXLCell AddExcelCell(IXLWorksheet ws, int row, int col, string value, string bgColor, bool bold
						, XLAlignmentHorizontalValues hAlign, XLBorderStyleValues outsideBorder)
{
	var cell = ws.Cell(row, col).SetValue(value);
	cell.DataType = XLCellValues.Text;
	cell.Style.Alignment.Horizontal = hAlign;
	cell.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center;
	cell.Style.Border.OutsideBorder = outsideBorder;
	if (bold) cell.Style.Font.Bold = true;
	if (!string.IsNullOrEmpty(bgColor)) cell.Style.Fill.BackgroundColor = XLColor.FromHtml(bgColor);

	return cell;
}

* AddExcelCell() 지정한 셀에 문자열을 표시하고 병합한다.

public IXLRange AddExcelCell(IXLWorksheet ws, int row, int col, int rowSpan, int colSpan, string value, string bgColor, int width)
{
	var endRow = (rowSpan > 1) ? row + rowSpan - 1 : row;
	var endCol = (colSpan > 1) ? col + colSpan - 1 : col;

	var rg = ws.Range(row, col, endRow, endCol);
	rg.Merge();
	rg.Cell(1, 1).SetValue(value);
	rg.DataType = XLCellValues.Text;
	rg.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
	rg.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center;
	rg.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
	if (!string.IsNullOrEmpty(bgColor)) rg.Style.Fill.BackgroundColor = XLColor.FromHtml(bgColor);
	if (width > 0) rg.FirstCell().WorksheetColumn().Width = width;

	return rg;
}

public IXLRange AddExcelCell(IXLWorksheet ws, int row, IXLRange range, int rowSpan, int colSpan, string value, string bgColor, int width)
{
	var col = range.Cell(1, 1).WorksheetColumn().ColumnNumber() + range.ColumnCount();
	var endRow = (rowSpan > 1) ? row + rowSpan - 1 : row;
	var endCol = (colSpan > 1) ? col + colSpan - 1 : col;

	var rg = ws.Range(row, col, endRow, endCol);
	rg.Merge();
	rg.Cell(1, 1).SetValue(value);
	rg.DataType = XLCellValues.Text;
	rg.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
	rg.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center;
	rg.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
	if (!string.IsNullOrEmpty(bgColor)) rg.Style.Fill.BackgroundColor = XLColor.FromHtml(bgColor);
	if (width > 0) rg.FirstCell().WorksheetColumn().Width = width;

	return rg;
}

* AddExcelFormularCell() 지정한 셀에 엑셀 수식을 표시한다.

public IXLCell AddExcelFormularCell(IXLWorksheet ws, int row, int col, string formular, string bgColor, bool bold, string numberFormat)
{
	var cell = ws.Cell(row, col);
	if (!string.IsNullOrEmpty(formular))
	{
		cell.DataType = XLCellValues.Number;
		if (!string.IsNullOrEmpty(numberFormat)) cell.Style.NumberFormat.Format = numberFormat;
		cell.SetFormulaA1(formular);
	}

	cell.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center;
	cell.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
	if (bold) cell.Style.Font.Bold = true;
	if (!string.IsNullOrEmpty(bgColor)) cell.Style.Fill.BackgroundColor = XLColor.FromHtml(bgColor);

	return cell;
}

* DownloadExcel() 서버의 엑셀 파일을 다운로드한다.

	/// 
	/// 서버의 엑셀 파일을 다운로드한다.
	///		다운로드 후에는 서버의 엑셀 파일을 삭제한다.
	/// 
	/// 실제 서버 물리 경로
	/// 엑셀 파일명
	public void DownloadExcel(string filePath, string fileName)
	{
		//한글 깨어짐 방지
		var saveFileName = HttpUtility.UrlEncode(fileName).Replace("+", "%20");
		//var fullPath = filePath + fileName;

		var response = System.Web.HttpContext.Current.Response;

		//---------------------------------------------------------------------
		//엑셀 파일 다운로드
		//---------------------------------------------------------------------
		//서버의 엑셀 파일 다운로드 후 몇 바이트 늘어남 -> 엑셀 열기 선택 시 복구 메시지 표시
		//---------------------------------------------------------------------
		//response.ClearContent();
		//response.Clear();
		//response.Charset = "utf-8";
		//response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8");
		////response.ContentType = "application/vnd.msexcel";
		//response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
		//response.AddHeader("Content-Disposition", string.Format(@"attachment; filename=""{0}"";", saveFileName));
		////response.TransmitFile(Server.MapPath("/" + fileName));
		//response.TransmitFile(fullPath);
		//response.Flush();

		//엑셀 파일 삭제
		//var deleteFile = new System.IO.FileInfo(fullPath);
		//if (deleteFile.Exists)
		//{
		//	System.IO.File.Delete(fullPath);
		//}

		//response.End();

		//---------------------------------------------
		//제네릭 처리기 사용
		//---------------------------------------------
		//열기 선택 시 엑셀 파일이 읽기 전용으로 열림
		//---------------------------------------------
		response.Redirect(string.Format("~/DownloadExcelFile.ashx?fileName={0}", saveFileName));
	}

* DownloadExcelFile.ashx 파일 내용

<%@ WebHandler Language="C#" Class="DownloadExcelFile" %>

using System;
using System.IO;
using System.Web;

public class DownloadExcelFile : IHttpHandler
{
	public void ProcessRequest(HttpContext context)
	{
		var request = context.Request;
		var response = context.Response;
		var fileName = request.QueryString["fileName"];

		if (!string.IsNullOrEmpty(fileName))
		{
			var saveFileName = HttpUtility.UrlEncode(fileName).Replace("+", "%20");
			var fullPath = string.Format("{0}{1}", context.Server.MapPath(@"~/Download/"), fileName);	//다운로드 경로
			
			response.ClearContent();
			response.Clear();
			response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
			response.AddHeader("Content-Disposition", string.Format(@"attachment; filename=""{0}"";", saveFileName));
			response.TransmitFile(fullPath);
			response.Flush();

			//엑셀 파일 삭제
			var deleteFile = new FileInfo(fullPath);
			if (deleteFile.Exists)
			{
				File.Delete(fullPath);
			}
			
			response.End();
		}
		else
		{
			var script = "<script type='text/javascript'>alert('엑셀 파일을 찾을 수 없습니다.');history.back();</script>";
			response.Write(script);
			response.End();
		}
	}

	public bool IsReusable
	{
		get
		{
			return false;
		}
	}
}

※ 사용방법

using(var wb = new new XLWorkbook())
{
	var ws = AddWorksheet(wb, "Test Sheet");

	var row = 1;
	var col = 1;
	for (var i = 0; i < list.Length; i++)
	{
		col = 1;

		AddExcelCell(ws, row, col++, list[i]["COL1"].ToString());
		AddExcelCell(ws, row, col++, list[i]["COL2"].ToString());

		row++;
	}
	
	ws.Columns().AdjustToContents();		//열 너비 자동설정(데이터양이 많을 경우 속도가 매우 느려짐)
	wb.SaveAs(@"d:\\example.xlsx");		//서버의 지정한 경로에 저장

	DownloadExcel(@"d:\\example.xlsx");	//서버의 경로에 저장되므로 사용자는 다운로드 필요
}
※ 주의사항
ws.Columns().AdjustToContents();
열 너비 자동설정하는 명령어인데 데이터양이 조금이라도 많을 경우 속도가 매우 느려지므로 조심해서 사용하자.