您的位置:首页 > 编程语言 > Java开发

简单封装POI导出excel

2017-07-31 22:07 411 查看

简单封装POI导出excel

Apache POI是一套根据Office Open XML标准(OOXML)和Microsoft
OLE 2复合文档格式(OLE2)来处理各种文件格式的Java API,在应用中经常用来和Microsoft
Office系列产品对接,在和excel对接是,需要处理excel繁琐的单元格,下面提供一个在Spring环境下导出excel的简单框架,减少对单元格的繁琐处理,减少重复搬砖,提高开发效率。

1. 依赖

<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.14</version>
</dependency>

2. Excel导出配置

1) 导出excel的样式、数据配置文件

导出excel时,主要逻辑无非是将数据填充到excel单元格中,再设置单元格样式,封装POI对excel单元格的操作,只需要定义预先约定的配置文件,封装类再解析配置文件,得到被导出excel每行、每个单元格的数据,操作单元格,最后生成excel文件,返回给用户。

下面是约定的简单配置

<?xml version="1.0" encoding="UTF-8"?>
<excel name="export.xls">
<sheet data-list="data1" desc="" field="examName">
<title desc="" field="examName" border="thin" height="40" background-color="41" align="center" v-align="center" wrap="true" bold="bold" font-size="25" font-color="12" font-name="黑体"></title>
<headers border="thin" height="25" background-color="43" align="center" v-align="center" wrap="true" bold="bold" font-size="20" font-name="宋体" >
<column header="名称" field="examName" type="String" border="thin" width="30" height="20" background-color="" align="center" v-align="top" wrap="true" bold="" font-size="18" font-name="宋体"></column>
<column header="测试1" field="schoolYear" type="String" border="thin" width="20" height="20" background-color="" align="right" v-align="center" wrap="true" bold="" font-size="18" font-name="宋体"></column>
<column header="测试2" field="term" type="String" border="thin" width="40" height="20" background-color="" align="left" v-align="" wrap="bottom" bold="true" font-size="18" font-name="隶书"></column>
</headers>
</sheet>
<sheet data-list="data1" desc="11111" field="examName">
<title desc="but" field="examName" border="thin" height="40" background-color="41" align="center" v-align="center" wrap="true" bold="bold" font-size="25" font-color="12" font-name="黑体"></title>
<headers border="thin" height="25" background-color="43" align="center" v-align="center" wrap="true" bold="bold" font-size="20" font-name="宋体" >
<column header="名称" field="examName" type="String" border="thin" width="30" height="20" background-color="" align="center" v-align="top" wrap="true" bold="" font-size="18" font-name="宋体"></column>
<column header="测试1" field="schoolYear" type="String" border="thin" width="20" height="20" background-color="" align="right" v-align="center" wrap="true" bold="" font-size="18" font-name="宋体"></column>
<column header="测试2" field="term" type="String" border="thin" width="40" height="20" background-color="" align="left" v-align="" wrap="bottom" bold="true" font-size="18" font-name="隶书"></column>
</headers>
</sheet>
</excel>

2) 配置解析器

配置解析器ExcelConfigHelper负责解析导出配置,生成程序可读的导出excel配置ExcelConfigVO对象

public class ExcelConfigHelper {
public static ExcelConfigVO GetExcelConfig(String configPath) {
ExcelConfigVO config = new ExcelConfigVO();
SAXReader reader = new SAXReader();
try {
Document doc = reader.read(new File(configPath));
Element root = doc.getRootElement();

config.setName(root.attributeValue("name"));

List<SheetConfigVO> sheetList = new ArrayList<SheetConfigVO>();
config.setSheetList(sheetList);

Iterator<Element> si = root.elementIterator();
while (si.hasNext()) {
Element se = si.next();

SheetConfigVO sc = new SheetConfigVO();
sheetList.add(sc);

sc.setDataList(se.attributeValue("data-list"));
sc.setDesc(se.attributeValue("desc"));
sc.setField(se.attributeValue("field"));

Element te = se.element("title");
if (null != te) {
sc.setTitleStyle(getStyleConfig(te));
}

Element he = se.element("headers");
if (null != he) {
sc.setHeaderStyle(getStyleConfig(he));
}
List<ColumnConfigVO> columnList = new ArrayList<ColumnConfigVO>();
sc.setColumnList(columnList);
Iterator<Element> ci = he.elementIterator();
while (ci.hasNext()) {

Element ce = ci.next();
ColumnConfigVO cc = getColumnConfig(ce);
columnList.add(cc);

}
}
} catch (DocumentException e) {

e.printStackTrace();
}
return config;
}

private static StyleConfigVO getStyleConfig(Element e) {
StyleConfigVO style = new StyleConfigVO();
style.setField(e.attributeValue("field"));
style.setDesc(e.attributeValue("desc"));
style.setBorder(e.attributeValue("border"));
style.setWidth(e.attributeValue("width"));
style.setHeight(e.attributeValue("height"));
style.setBgcolor(e.attributeValue("background-color"));
style.setAlign(e.attributeValue("align"));
style.setValign(e.attributeValue("v-align"));
style.setWrap(e.attributeValue("wrap"));
style.setBold(e.attributeValue("bold"));
style.setFontSize(e.attributeValue("font-size"));
style.setFontName(e.attribu
4000
teValue("font-name"));
style.setFontColor(e.attributeValue("font-color"));
return style;
}

private static ColumnConfigVO getColumnConfig(Element e) {
ColumnConfigVO c = new ColumnConfigVO();
c.setField(e.attributeValue("field"));
c.setHeader(e.attributeValue("header"));

StyleConfigVO style = getStyleConfig(e);
c.setStyle(style);
return c;
}
}

Excel配置类

ExcelConfigVO

public class ExcelConfigVO implements Serializable {

/**
*
*/
private static final long serialVersionUID = -6669292508345659358L;

private String name;

private List<SheetConfigVO> sheetList;

SheetConfigVO

public class SheetConfigVO implements Serializable {

/**
*
*/
private static final long serialVersionUID = -7809672890306591286L;

private String dataList;

private String desc;

private String field;

private StyleConfigVO titleStyle;

private StyleConfigVO headerStyle;

private List<ColumnConfigVO> columnList;

StyleConfigVO 

public class StyleConfigVO implements Serializable {

/**
*
*/
private static final long serialVersionUID = 2747357536186545711L;

private String desc;

private String field;

private String border;

private String width;

private String height;

private String bgcolor;

private String align;

private String valign;

private String wrap;

private String bold;

private String fontSize;

private String fontName;

private String fontColor;

ColumnConfigVO 

public class ColumnConfigVO implements Serializable {

/**
*
*/
private static final long serialVersionUID = 5303919948113915294L;

private String header;

private String field;

private StyleConfigVO style;

3. 根据配置和数据生成excel

Excel生成器ExcelExportHelper根据配置和数据生成excel

public class ExcelExportHelper {

private static final Logger log = LoggerFactory.getLogger(ExcelExportHelper.class);

public static HSSFWorkbook export(Map<String, Object> map, ExcelConfigVO config) {
try {

HSSFWorkbook hw = new HSSFWorkbook();

int sheetIndex = 1;
for (SheetConfigVO sc : config.getSheetList()) {

// dataList数据集合,desc是sheet名称,field是sheet名称在数据集合中的字段,后面二者取一个
String dataList = sc.getDataList();
String desc = sc.getDesc();
String field = sc.getField();
List<Object> datas = (List<Object>) map.get(dataList);

if (StringUtils.isEmpty(desc) && !CollectionUtils.isEmpty(datas) && !StringUtils.isEmpty(field)) {
Object obj = datas.get(0);
Field f = obj.getClass().getDeclaredField(field);
f.setAccessible(true);
desc = (String) f.get(obj);
}

if (StringUtils.isEmpty(desc)) {
desc = "sheet" + sheetIndex;
}

HSSFSheet sheet = hw.createSheet(desc);

if (null != sc.getTitleStyle()) {
StyleConfigVO ts = sc.getTitleStyle();
String tdesc = ts.getDesc();
String tfield = ts.getField();

if (StringUtils.isEmpty(tdesc) && !CollectionUtils.isEmpty(datas) && !StringUtils.isEmpty(tfield)) {
Object obj = datas.get(0);
Field f = obj.getClass().getDeclaredField(tfield);
f.setAccessible(true);
tdesc = (String) f.get(obj);
}

if (StringUtils.isEmpty(tdesc)) {
tdesc = "title" + sheetIndex;
}

HSSFCellStyle titleStyle = getCellStyle(hw, ts);
int rindex = 0;
HSSFRow row = sheet.createRow(rindex++);
if (!StringUtils.isEmpty(ts.getHeight())) {
row.setHeightInPoints(Short.valueOf(ts.getHeight()));
}
HSSFCell cell = row.createCell(0);
cell.setCellStyle(titleStyle);
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
cell.setCellValue(desc);
if (!CollectionUtils.isEmpty(sc.getColumnList()) && sc.getColumnList().size() > 1) {
for (int i = 1; i < sc.getColumnList().size(); i++) {
cell = row.createCell(i);
cell.setCellStyle(titleStyle);
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
cell.setCellValue("");
}
CellRangeAddress merge = new CellRangeAddress(rindex - 1, rindex - 1, 0,
sc.getColumnList().size() - 1);
sheet.addMergedRegion(merge);
}

StyleConfigVO hs = sc.getHeaderStyle();
HSSFCellStyle headerstyle = getCellStyle(hw, hs);
row = sheet.createRow(rindex++);
if (!StringUtils.isEmpty(hs.getHeight())) {
row.setHeightInPoints(Short.valueOf(hs.getHeight()));
}

Map<Integer, HSSFCellStyle> styleMap = new HashMap<Integer, HSSFCellStyle>();
if (!CollectionUtils.isEmpty(sc.getColumnList())) {
for (int i = 0; i < sc.getColumnList().size(); i++) {
ColumnConfigVO column = sc.getColumnList().get(i);
styleMap.put(i, getCellStyle(hw, column.getStyle()));

cell = row.createCell(i);
cell.setCellStyle(headerstyle);
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
cell.setCellValue(column.getHeader());
if (null != column.getStyle() && !StringUtils.isEmpty(column.getStyle().getWidth())) {
sheet.setColumnWidth(i, Short.valueOf(column.getStyle().getWidth()) * 256);
}

}
}

for (Object obj : datas) {
row = sheet.createRow(rindex++);
for (int i = 0; i < sc.getColumnList().size(); i++) {

ColumnConfigVO column = sc.getColumnList().get(i);

if (i == 0 && !StringUtils.isEmpty(column.getStyle().getHeight())) {

row.setHeightInPoints(Short.valueOf(column.getStyle().getHeight()));
}
styleMap.put(i, getCellStyle(hw, column.getStyle()));

cell = row.createCell(i);
cell.setCellStyle(styleMap.get(i));
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
String val = "";
Field f = obj.getClass().getDeclaredField(column.getField());
f.setAccessible(true);
val = (String) f.get(obj);
cell.setCellValue(null == val ? "" : val);
}
}
}

sheetIndex++;
}

return hw;
} catch (NoSuchFieldException e) {

log.error("", e);
} catch (SecurityException e) {

log.error("", e);
} catch (IllegalArgumentException e) {

log.error("", e);
} catch (IllegalAccessException e) {

log.error("", e);
}
return null;
}

private static HSSFCellStyle getCellStyle(HSSFWorkbook hw, StyleConfigVO ts) {
HSSFCellStyle titlestyle = hw.createCellStyle();
HSSFFont titlefont = hw.createFont();

if (!StringUtils.isEmpty(ts.getBold()) && "BOLD".equalsIgnoreCase(ts.getBold().trim())) {
titlefont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
}

if (!StringUtils.isEmpty(ts.getFontName())) {
titlefont.setFontName(ts.getFontName().trim());
}

if (!StringUtils.isEmpty(ts.getFontSize())) {
titlefont.setFontHeightInPoints(Short.valueOf(ts.getFontSize()));
}

if (!StringUtils.isEmpty(ts.getFontColor())) {
titlefont.setColor(Short.valueOf(ts.getFontColor()));
}
titlestyle.setFont(titlefont);

if (!StringUtils.isEmpty(ts.getBorder())) {
if ("THIN".equalsIgnoreCase(ts.getBorder().trim())) {
titlestyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
titlestyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
titlestyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
titlestyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
} else if ("NONE".equalsIgnoreCase(ts.getBorder().trim())) {
titlestyle.setBorderBottom(HSSFCellStyle.BORDER_NONE);
titlestyle.setBorderLeft(HSSFCellStyle.BORDER_NONE);
titlestyle.setBorderRight(HSSFCellStyle.BORDER_NONE);
titlestyle.setBorderTop(HSSFCellStyle.BORDER_NONE);
} else if ("DOUBLE".equalsIgnoreCase(ts.getBorder().trim())) {
titlestyle.setBorderBottom(HSSFCellStyle.BORDER_DOUBLE);
titlestyle.setBorderLeft(HSSFCellStyle.BORDER_DOUBLE);
titlestyle.setBorderRight(HSSFCellStyle.BORDER_DOUBLE);
titlestyle.setBorderTop(HSSFCellStyle.BORDER_DOUBLE);
} else if ("DOTTED".equalsIgnoreCase(ts.getBorder().trim())) {
titlestyle.setBorderBottom(HSSFCellStyle.BORDER_DOTTED);
titlestyle.setBorderLeft(HSSFCellStyle.BORDER_DOTTED);
titlestyle.setBorderRight(HSSFCellStyle.BORDER_DOTTED);
titlestyle.setBorderTop(HSSFCellStyle.BORDER_DOTTED);
} else if ("DASHED".equalsIgnoreCase(ts.getBorder().trim())) {
titlestyle.setBorderBottom(HSSFCellStyle.BORDER_DASHED);
titlestyle.setBorderLeft(HSSFCellStyle.BORDER_DASHED);
titlestyle.setBorderRight(HSSFCellStyle.BORDER_DASHED);
titlestyle.setBorderTop(HSSFCellStyle.BORDER_DASHED);
} else if ("MEDIUM".equalsIgnoreCase(ts.getBorder().trim())) {
titlestyle.setBorderBottom(HSSFCellStyle.BORDER_MEDIUM);
titlestyle.setBorderLeft(HSSFCellStyle.BORDER_MEDIUM);
titlestyle.setBorderRight(HSSFCellStyle.BORDER_MEDIUM);
titlestyle.setBorderTop(HSSFCellStyle.BORDER_MEDIUM);
}
}

if (!StringUtils.isEmpty(ts.getAlign())) {
String align = ts.getAlign().toUpperCase().trim();
switch (align) {
case "CENTER":
titlestyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
case "LEFT":
titlestyle.setAlignment(HSSFCellStyle.ALIGN_LEFT);
case "RIGHT":
titlestyle.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
case "FILL":
titlestyle.setAlignment(HSSFCellStyle.ALIGN_FILL);
case "GENERAL":
titlestyle.setAlignment(HSSFCellStyle.ALIGN_GENERAL);
default:
titlestyle.setAlignment(HSSFCellStyle.ALIGN_JUSTIFY);
}

}

if (!StringUtils.isEmpty(ts.getValign())) {
String valign = ts.getValign().toUpperCase().trim();
switch (valign) {
case "CENTER":
titlestyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
case "BOTTOM":
titlestyle.setAlignment(HSSFCellStyle.VERTICAL_BOTTOM);
case "TOP":
titlestyle.setAlignment(HSSFCellStyle.VERTICAL_TOP);
default:
titlestyle.setAlignment(HSSFCellStyle.VERTICAL_JUSTIFY);
}

}

if (!StringUtils.isEmpty(ts.getBgcolor())) {
titlestyle.setFillForegroundColor(Short.valueOf(ts.getBgcolor()));
titlestyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
}

if (!StringUtils.isEmpty(ts.getWrap())) {
titlestyle.setWrapText(Boolean.valueOf(ts.getWrap()));
}

return titlestyle;
}

public static String getFileName(String fileName, ExcelConfigVO config) {
if (StringUtils.isEmpty(fileName)) {
fileName = config.getName();
}

if (StringUtils.isEmpty(fileName)) {
fileName = "export.xls";
}
return fileName;
}
}

4. 导出逻辑

1) 获取导出任务

导出任务接口,导出特定数据时需要实现接口,给配置解析器提供特定的配置,给excel生成器提供特定的数据。

 public interface IExcelExportProcessor {

/**
* 配置文件路径
*
* @return
*/
public String getConfigPath();

/**
* 导出文件名
*
* @return
*/
public String getFilename();

/**
* 查询数据
*
* @param queryMap
* 查询参数
* @return 导出数据
*/
public Map<String, Object> getDatas(Map<String, Object> queryMap);
}
导出任务实现样例

 @Component("excelExport.seat")
public class ExportSeatProcessor implements IExcelExportProcessor {

private static final Logger log = LoggerFactory.getLogger(ExportSeatProcessor.class);

@Override
public String getConfigPath() {

return "";
}

@Override
public String getFilename() {

return null;
}

@Override
public Map<String, Object> getDatas(Map<String, Object> queryMap) {

return null;
}

}
2) 导出接口

导出接口根据请求参数得到导出任务Bean和数据请求参数,通过导出任务Bean获取导出配置,数据,导出文件名,再调用配置解析器,excel生成器,生成excel并返回。

RequestMapping(value = "/export", method = RequestMethod.GET)
public void test(HttpServletRequest req, HttpServletResponse res) throws IOException {
String processorName = req.getParameter("processor");

if (StringUtils.isEmpty(processorName)) {
res.getWriter().println("parameter error!");
return;
}

IExcelExportProcessor processor = (IExcelExportProcessor) ExcelExportContext.getApplicationContext()
.getBean(processorName);
if (null == processor) {
res.getWriter().println("parameter error!");
return;
}

Map<String, Object> queryMap = getParameterMap(req);
String fileName = processor.getFilename();
String configPath = processor.getConfigPath();
Map<String, Object> map = processor.getDatas(queryMap);

ExcelConfigVO config = ExcelConfigHelper.GetExcelConfig(configPath);
fileName = ExcelExportHelper.getFileName(fileName, config);

HSSFWorkbook hw = ExcelExportHelper.export(map, config);
res.setContentType("application/octet-stream");
res.setHeader("Content-disposition", "attachment;filename=" + new String(fileName.getBytes(), "ISO-8859-1"));
OutputStream out = null;
try {

out = res.getOutputStream();
hw.write(out);
} catch (IOException e) {

log.error("export excel error", e);
} finally {
try {
if (null != out) {
out.close();
}
} catch (IOException e) {
log.error("export excel error", e);
}

}
}


http GET请求 url?processorName=xxx&name=xxx$yyy=xxx,增加导出数据查询参数,即可导出excel。


([b]完)[/b]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java POI excel