import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.function.Function;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
public class ExeclExportUtils {
// 缺省值
private static String DEFAULT_VALUE = "-";
public static <T> void exportExcel(HttpServletResponse response, String rawExeclName, List<T> list, String exportExeclName, Object... rules) throws Exception {
response.setHeader("content-Type", "application/vnd.ms-excel");
response.setHeader("Content-Disposition", new StringBuilder("attachment;filename=").append(URLEncoder.encode(exportExeclName, "utf-8")).toString());
XSSFWorkbook wb = generate(rawExeclName, list, rules);
try {
wb.write(response.getOutputStream());
} finally {
wb.close();
}
}
private static <T> XSSFWorkbook generate(String rawExeclName, List<T> list, Object... rules) throws IOException {
InputStream is = new PathMatchingResourcePatternResolver().getResource("/execl/"+rawExeclName).getInputStream();
XSSFWorkbook wb = new XSSFWorkbook(is);
XSSFSheet sheet = wb.getSheetAt(0);
write(list, sheet, rules);
return wb;
}
private static <T> void write(List<T> list, XSSFSheet sheet, Object... rules) {
for (int i = 0; i < list.size(); i++) {
XSSFRow row = sheet.createRow(i+1);
Object obj = list.get(i);
for (int j = 0; j < rules.length; j++) {
row.createCell(j).setCellValue(getValue(obj, rules[j], i));
}
}
}
@SuppressWarnings("unchecked")
private static String getValue(Object obj, Object rule, int i) {
String val;
if (rule instanceof String) {
try {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(rule.toString(), obj.getClass());
val = propertyDescriptor.getReadMethod().invoke(obj, new Object[]{}).toString();
if (val == null) {
val = DEFAULT_VALUE;
}
} catch (Exception e) {
log.error("generate - getVal", e);
return "";
}
}else if(rule instanceof Function<?, ?>) {
val = ((Function<Object, Object>)rule).apply(obj).toString();
}else if(rule instanceof ExeclIndexConvert<?>) {
val = ((ExeclIndexConvert<Object>)rule).convert(obj, i);
}else {
log.error("不能识别的转换器 !");
return "";
}
return val;
}
public interface ExeclIndexConvert<T> {
String convert(T t, int index);
}
}