안녕하세요. 명월입니다.
지난 포스팅에서 C#에서 엑셀파일을 만드는 라이브러리 NPOI에 대해서 설명했습니다.
이어서 이번에는 처음부터 만드는 것이 아니라 템플릿을 읽어 드려서 필요한 데이터만 바꾸는 방법으로 설명하겠습니다.
먼저 하나의 예제 데이터를 만들었습니다.
예제 파일 첨부입니다.
예제 데이터는 첫번째 컬럼은 월, 2번째 컬럼은 기온 평균, 3번째 컬럼은 오전 기온, 4번째 컬럼은 오후 기온으로 그래프는 평균을 나타내는 값으로 했습니다.
이제 프로그램을 작성하겠습니다.
먼저 NUGET을 통해 NPOI를 다운, 참조하겠습니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
//공통 NPOI
using NPOI;
using NPOI.SS.UserModel;
//표준 xls 버젼 excel시트
using NPOI.HSSF;
using NPOI.HSSF.UserModel;
//확장 xlsx 버젼 excel 시트
using NPOI.XSSF;
using NPOI.XSSF.UserModel;
namespace NPOIExample
{
class Program
{
static void Main(string[] args)
{
new Program();
Console.WriteLine("Press Any Key...");
Console.ReadKey();
}
public Program()
{
var version = "xls";
//var version = "xlsx";
// Workbook 취득.
var workbook = GetWorkbook(@"d:\work\Test.xls", version);
// Workbook안에 시트 취득.
var sheet = workbook.GetSheetAt(0);
// Sheet에서 셀 취득 후 데이터 설정
// 1월 오전
GetCell(sheet, 1, 2).SetCellValue(-5);
// 1월 오후
GetCell(sheet, 1, 3).SetCellValue(0);
// 2월 오전
GetCell(sheet, 2, 2).SetCellValue(-10);
// 2월 오후
GetCell(sheet, 2, 3).SetCellValue(-5);
// 3월 오전
GetCell(sheet, 3, 2).SetCellValue(0);
// 3월 오후
GetCell(sheet, 3, 3).SetCellValue(2);
// 4월 오전
GetCell(sheet, 4, 2).SetCellValue(4);
// 4월 오후
GetCell(sheet, 4, 3).SetCellValue(10);
// 5월 오전
GetCell(sheet, 5, 2).SetCellValue(10);
// 5월 오후
GetCell(sheet, 5, 3).SetCellValue(15);
// 6월 오전
GetCell(sheet, 6, 2).SetCellValue(18);
// 6월 오후
GetCell(sheet, 6, 3).SetCellValue(25);
// 7월 오전
GetCell(sheet, 7, 2).SetCellValue(23);
// 7월 오후
GetCell(sheet, 7, 3).SetCellValue(28);
// 8월 오전
GetCell(sheet, 8, 2).SetCellValue(25);
// 8월 오후
GetCell(sheet, 8, 3).SetCellValue(31);
// 9월 오전
GetCell(sheet, 9, 2).SetCellValue(25);
// 9월 오후
GetCell(sheet, 9, 3).SetCellValue(29);
// 10월 오전
GetCell(sheet, 10, 2).SetCellValue(15);
// 10월 오후
GetCell(sheet, 10, 3).SetCellValue(25);
// 11월 오전
GetCell(sheet, 11, 2).SetCellValue(11);
// 11월 오후
GetCell(sheet, 11, 3).SetCellValue(17);
// 12월 오전
GetCell(sheet, 12, 2).SetCellValue(5);
// 12월 오후
GetCell(sheet, 12, 3).SetCellValue(9);
// 함수값 재 설정
for (int i = 1; i <= 12; i++)
{
GetCell(sheet, i, 1).SetCellFormula(String.Format("AVERAGE(C{0}:D{0})", i + 1));
}
WriteExcel(workbook, @"d:\work\result." + version);
}
// Workbook 읽어드리기
public IWorkbook GetWorkbook(string filename, string version)
{
using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
//표준 xls 버젼
if ("xls".Equals(version))
{
return new HSSFWorkbook(stream);
}
//확장 xlsx 버젼
else if ("xlsx".Equals(version))
{
return new XSSFWorkbook(stream);
}
throw new NotSupportedException();
}
}
// Sheet로 부터 Row를 취득, 생성하기
public IRow GetRow(ISheet sheet, int rownum)
{
var row = sheet.GetRow(rownum);
if (row == null)
{
row = sheet.CreateRow(rownum);
}
return row;
}
// Row로 부터 Cell를 취득, 생성하기
public ICell GetCell(IRow row, int cellnum)
{
var cell = row.GetCell(cellnum);
if (cell == null)
{
cell = row.CreateCell(cellnum);
}
return cell;
}
public ICell GetCell(ISheet sheet, int rownum, int cellnum)
{
var row = GetRow(sheet, rownum);
return GetCell(row, cellnum);
}
public void WriteExcel(IWorkbook workbook, string filepath)
{
using (var file = new FileStream(filepath, FileMode.Create, FileAccess.Write))
{
workbook.Write(file);
}
}
}
}
기존 0과 2로 되어있던 데이터를 입력해서 위 결과 값처럼 값이 바뀌면서 그래프의 모습도 바뀌었습니다. 소스 중에 함수 재 설정 부분이 있습니다. 이유는 모르겠으나 C열과 D열의 데이터가 바뀌어도 함수식으로 재 계산되어 B열이 값이 바뀌지 않습니다.
그래서 그 부분에 Formula함수를 써서 다시 재 입력을 하면 C열과 D열의 값이 계산되어 입력됩니다.
실제 업무에서도 엑셀을 다루는 영역이면 프로그램 안에서 엑셀을 1부터 만들어서 출력하기 보다는 스타일이나 그래프, 서식등을 미리 템플릿에 만들어 놓고 프로그램에서는 값만 넣어서 출력하는 형태로 많이 사용합니다. 물론 출력 값이 매우 동적으로 사양에 따라 엑셀 시트 모습이 천차 만별이면 어쩔 수 없지만, 그런 경우는 많지도 않고 정해진 포멧이 값만 바뀌는 형태가 대부분이기 때문에 위와 같이 많이 작성합니다.
첨부파일입니다.
'Development note > C#' 카테고리의 다른 글
[C#] Zip 압축 코드 소스 (3) | 2019.06.03 |
---|---|
[C#] System.Net.Mail을 이용하여 메일 보내기 (0) | 2019.05.28 |
[C#] Newtonsoft.JSON를 이용한 Json 다루기 (0) | 2019.05.15 |
[C#] iTextSharp을 이용한 PDF 만들기 (0) | 2019.05.14 |
[C#] NPOI를 이용한 엑셀 파일 만들기 (1) | 2019.05.14 |
[C#] Zip 압축 해제 코드 소스 (0) | 2019.05.10 |
[C#] 계산기 프로그램 (1) | 2015.06.07 |
[C#] 소켓통신 - 서버에서 특정 클라이언트만 메시지 전송 (4) | 2015.05.14 |