通用Excel下載
阿新 • • 發佈:2019-01-07
用於excel生成,下載。
1.自定義Excel註解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 用於Excel生成,註明列的名稱和其他屬性
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelColumnName {
/**
* 列的表頭名稱
* @return
*/
String name() default "-";
/**
* 用於日期格式化的字串,預設 yyyy-MM-dd HH:mm:ss
* @return
*/
String dateFormat() default "yyyy-MM-dd hh:mm:ss";
}
2.Excel通用類
import com.pingan.haofang.leshan.common.utils.DateUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.springframework. http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Excel file generator
*/
public class ExcelGenerator {
private HSSFWorkbook workbook;
public ExcelGenerator() {
this.workbook = new HSSFWorkbook();
}
private List<Field> getFieldsWithAnnotations(Class rowClass) {
// get all fields with annotation "ExcelColumnName"
List<Field> rowFields = Arrays.stream(rowClass.getDeclaredFields())
.filter(f -> f.isAnnotationPresent(ExcelColumnName.class))
.collect(Collectors.toList());
return rowFields;
}
private List<String> getColumnNames(Class rowClass) {
List<Field> rowFields = getFieldsWithAnnotations(rowClass);
List<String> rowNames = rowFields.stream()
.map(f -> getColumnName(f)).collect(Collectors.toList());
return rowNames;
}
private String getColumnName(Field columnField) {
return columnField.getAnnotation(ExcelColumnName.class).name();
}
private String getDateFormat(Field columnField) {
return columnField.getAnnotation(ExcelColumnName.class).dateFormat();
}
/**
* 通過物件列表構造Excel Sheet
* @param sheetName 插入的sheet名稱
* @param rowClass rowObjs的型別
* @param rowObjs 構成表格的物件列表
* @throws IllegalAccessException
*/
public void addSheetFromArray(String sheetName, Class rowClass, Object[] rowObjs) throws IllegalAccessException {
addSheetFromArray(sheetName, rowClass, rowObjs, Collections.emptyList(), Collections.emptyMap());
}
/**
* 通過物件列表構造Excel Sheet
* @param sheetName 插入的sheet名稱
* @param rowClass rowObjs的型別
* @param rowObjs 構成表格的物件列表
* @param columnsToShow 要顯示的列(如不需要請留空)
* @param columnMapping 需要重新命名的列mapping
* @throws IllegalAccessException
*/
public void addSheetFromArray(String sheetName, Class rowClass, Object[] rowObjs,
List<String> columnsToShow, Map<String, String> columnMapping)
throws IllegalAccessException {
List<Field> rowFields;
// create new sheet on workbook
HSSFSheet sheet = this.workbook.createSheet(sheetName);
// create header
HSSFRow head = sheet.createRow(0);
// filter columns to show
if (columnsToShow != null && !columnsToShow.isEmpty()) {
List<Field> allFields = getFieldsWithAnnotations(rowClass);
Map<String, Field> fieldMap = new HashMap<String, Field>();
allFields.forEach(f -> {
String columnName = getColumnName(f);
fieldMap.put(columnName, f);
});
rowFields = columnsToShow.stream().map(c -> fieldMap.get(c)).collect(Collectors.toList());
} else {
// get all fields with annotation "ExcelColumnName"
rowFields = getFieldsWithAnnotations(rowClass);
}
// getColumnNames
List<String> columnNames = rowFields.stream().map(f -> getColumnName(f)).collect(Collectors.toList());
columnNames = columnNames.stream().map(name -> columnMapping.getOrDefault(name, name))
.collect(Collectors.toList());
// add column names to header
for (int i = 0; i < columnNames.size(); i++) {
head.createCell(i).setCellValue(columnNames.get(i));
}
// set all fields accessible
rowFields.forEach(f -> f.setAccessible(true));
// write data to sheet
for (int i = 0; i < rowObjs.length; i++) {
// create new row
HSSFRow dataRow = sheet.createRow(i+1);
// get object for current row
Object rowObj = rowObjs[i];
for (int j = 0; j < rowFields.size(); j++) {
// get current field value
Field field = rowFields.get(j);
Object cellValue = field.get(rowObj);
// set cell value with correct type
if(cellValue == null) {continue;}
if (field.getType() == boolean.class) {
dataRow.createCell(j).setCellValue((boolean)cellValue);
} else if (field.getType() == Calendar.class || field.getType() == Date.class) {
// generate Date format
HSSFCell cell = dataRow.createCell(j);
CellStyle cellStyle = workbook.createCellStyle();
CreationHelper helper = workbook.getCreationHelper();
String dateFormat = getDateFormat(field);
cellStyle.setDataFormat(helper.createDataFormat().getFormat(dateFormat));
if (field.getType() == Calendar.class) {
cell.setCellValue((Calendar) cellValue);
} else {
cell.setCellValue((Date) cellValue);
}
cell.setCellStyle(cellStyle);
} else if (field.getType() == String.class) {
dataRow.createCell(j).setCellValue(cellValue.toString());
} else {
String cellValueString = cellValue.toString();
try {
// if cell value can be convert to double
double cellValueDouble = Double.parseDouble(cellValueString);
dataRow.createCell(j).setCellValue(cellValueDouble);
} catch (NumberFormatException e) {
// if not, convert to string by default
dataRow.createCell(j).setCellValue(cellValueString);
}
}
}
}
}
public byte[] generateExcelFileContent() throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
workbook.write(outputStream);
return outputStream.toByteArray();
}
public static String generateExcelFileNameWithDate(String name) {
String date = DateUtils.formatDate(new Date(), "yyyy-MM-dd");
return name + date + ".xls";
}
public static String generateExcelFileNameWithDateUTF8(String name) {
try {
return URLEncoder.encode(generateExcelFileNameWithDate(name), "UTF-8");
} catch (UnsupportedEncodingException e) {
return "";
}
}
public ResponseEntity generateResponseEntity(String name) {
try {
byte[] body = this.generateExcelFileContent();
String fileName = generateExcelFileNameWithDateUTF8(name);
return ResponseEntity.ok()
.contentLength(body.length)
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName)
.contentType(MediaType.parseMediaType("application/vnd.ms-excel"))
.body(body);
} catch (Exception e) {
return ResponseEntity.badRequest().build();
}
}
}
3.程式碼示例
import com.pingan.haofang.common.excelutil.ExcelColumnName;
import com.pingan.haofang.common.excelutil.ExcelGenerator;
import com.pingan.haofang.leshan.common.constants.WebConstants;
import io.swagger.annotations.Api;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.Date;
/**
* Excel生成示例
*/
@RestController
@RequestMapping(WebConstants.WEB_PREFIX + "/example")
@Api(tags = "ExcelExample", description = "Excel生成示例")
public class ExcelExampleController {
@RequestMapping(value = "/download", method = RequestMethod.GET)
public ResponseEntity GenerateExcelFile() {
// 示例資料Array
ExampleClass[] exampleData = {
new ExampleClass("張三", "111222333", (float)-99.999, new Date("03/15/2018")),
new ExampleClass("隔壁老王", "444555666", (float)100.1, new Date("03/15/2018"))};
ExcelGenerator excelGenerator = new ExcelGenerator();
try {
excelGenerator.addSheetFromArray("Contacts", ExampleClass.class, exampleData);
byte[] body = excelGenerator.generateExcelFileContent();
String nowTime = DateFormatUtils.format(new Date(), "yyyy-MM-dd");
return ResponseEntity.ok()
.contentLength(body.length)
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="+ URLEncoder.encode("測試示例", "UTF-8")+nowTime+".xls")
.contentType(MediaType.parseMediaType("application/vnd.ms-excel"))
.body(body);
} catch (IllegalAccessException e) {
} catch (IOException e) {
}
return ResponseEntity.notFound().build();
}
// 需要轉換為Excel的資料類
class ExampleClass{
// 新增annotation註明該列表頭的名稱
@ExcelColumnName(name = "姓名")
private String name;
@ExcelColumnName(name = "電話號碼")
private String phoneNumber;
@ExcelColumnName(name = "薪水")
private float salary;
@ExcelColumnName(name = "過期", dateFormat = "yyyy-MM-dd")
private Date expriy;
public ExampleClass(String name, String phoneNumber, float salary, Date expiry) {
this.name = name;
this.phoneNumber = phoneNumber;
this.salary = salary;
this.expriy = expiry;
}
}
}