[회사일] GenericExcelView 만들기
현재 업무를 엑셀 파일로 처리하고 있기 때문에 엑셀 파일과의 연동을 필수적입니다. 따라서 시스템에 들어있는 정보를 엑셀로 받아볼 수 있게 하거나 엑셀 정보를 시스템에 올려서 DB에 저장되게 하는 것도 필요합니다.
엑셀 업로드야 엑셀 파일 형식이 도메인 클래스 마다 다를 테고 비즈니스 로직마다 다를테니 일반화하기 힘들지만(뭐 어떤 규칙을 정하면 일반화를 못할 것도 없겠지만..) 엑셀 다운로드 경우에는 일반화하기 좋습니다. 리포트 형식의 엑셀을 원하는게 아니라면 말이죠;; 그런건 여기서 받은 엑셀 파일을 기초데이터로 삼아서 다른 직원보고 편집해서 리포트 만들라고 시키면 될테니 이런 간단한 재고관리 시스템에 무리한 기능을 넣고 싶진 않군요.
어쨋든.. 일반화 시켜봅시다.
<page:mgtpage label="재고 관리">
<page:search label="재고 검색">
<s:input label="제품명" path="name" />
<s:input label="제품번호" path="number" />
<s:input label="색상" path="colorName" />
<s:select label="성별" path="sexValue" items="${ref.sexList}" />
<s:input label="공급업체" path="suppName" />
<s:input label="창고" path="locationName" />
<s:date label="날짜" fromPath="dateRange.from" toPath="dateRange.to"/>
</page:search>
<script type="text/javascript">
$(function() {
$("#smdis-grid").jqGrid({
colNames:['id', '제품명', '제품번호', '색상', '사이즈', '공급업체', '창고', '수량', '날짜'],
colModel :[
{name:'id', index:'id', width:55, hidden:true},
{name:'item.name', index:'item.name', width:90},
{name:'item.number', index:'item.number', width:90},
{name:'item.colorName', index:'item.color', width:90},
{name:'item.size', index:'item.size', width:90},
{name:'item.supp.name', index:'item.supp', width:80},
{name:'location.name', index:'location.name', width:80},
{name:'qty', index:'qty', width:80},
{name:'date', index:'date', width:80}
]
});
});
</script>
</page:mgtpage>
화면에 보여줄 그리드 정보가 들어있는 mgt.jsp 페이지 소스입니다. 태그 파일을 사용해서 중복 코드를 제거하고 여기서 꼭 다뤄야하는 정보만 남겨뒀습니다. 이 상태에서 엑셀을 일반화 시켜서 만들때 서버쪽으로 넘겨줘야 하는 정보가 들어있습니다. 컬럼명과 각 컬럼 값이 들어있는 path 정보입니다.
화면에 등록된 그리드 정보를 그대로 엑셀로 옮기고 싶다면 그 두 정보를 가져와야 합니다. 구현 과정을 전부다 설명하기는 다소 귀찮군요.. 흠.. 할일도 많으니까 대충 생략하겠습니다.
저기서 버튼을 누르면 컬럼 정보, Path 정보, 검색 매개변수들을 서버쪽으로 넘겨줍니다.
그럼 서버가 받아서 SpEL과 JExcel API와 스프링이 제공해주는 AbstractJExcelView 엑셀뷰를 사용해서 엑셀을 만들어 줍니다.
public class GenericExcelView extends AbstractJExcelView {
protected void buildExcelDocument(Map<String, Object> model, WritableWorkbook wb, HttpServletRequest req, HttpServletResponse res) throws Exception {
List<?> list = (List<?>) model.get("list");
String modelName = (String) model.get("modelName");
List<String> colNameList = (List<String>) model.get("colNameList");
List<String> colPathList = (List<String>) model.get("colPathList");
res.setHeader("Content-Disposition", "attachment; filename=" + modelName + ".xls");
WritableSheet sheet = wb.createSheet(modelName, 0);
for(int column = 0 ; column < colNameList.size() ; column++){
sheet.addCell(new Label(column, 0, colNameList.get(column)));
}
ExpressionParser parser = new SpelExpressionParser();
int row = 1;
for(Object object : list){
StandardEvaluationContext context = new StandardEvaluationContext(object);
for(int column = 0 ; column < colPathList.size() ; column++){
String path = colPathList.get(column).replace(".", "?.");
String value = parser.parseExpression(path).getValue(context, String.class);
sheet.addCell(new Label(column, row, value));
}
row++;
}
}
}
이걸 사용하도록 GenericController 쪽에도 기능을 추가해줬는데 그거야 뭐 간단하니깐. 생략하겠습니다. 이제 재고관리와 상품관리쪽에 엑셀 업로드를 만들어야겠습니다. 내일할까나;; 흠.