excel匯入匯出工具類
阿新 • • 發佈:2019-01-06
Excel匯入功能
匯入功能是將excel中的資料轉換成對應的javaBean。
實現思路
- 使用poi讀取excel表格
- 獲取每行表格中的單元格資訊,將單元格中的資料存入到對應的javaBean中。
- 寫一個註解類來標註javaBean中的那個屬性要與Excel中的資料進行對應。
- 運用java反射來獲取javaBean中的註解屬性。
程式碼實現
public class ImportExcelUtil {
private final Logger logger = LoggerFactory.getLogger(ImportExcelUtil.class);
private static final int DEFAULT_COUNT=20000;
private static final int DEFAULT_START_LINE=0;
public static <T> List<T> convertSheetToList(InputStream in,Class<T> clazz, boolean isExcel2003,
int startLine,int maxCount) throws Exception {
List<T> list = new ArrayList<>();
/** 根據版本選擇建立Workbook的方式 */
Workbook wb;
if (isExcel2003) {
wb = new HSSFWorkbook(in);
} else {
wb = new XSSFWorkbook(in);
}
if(null != wb){
//獲取第0個工作表格
Sheet sheet = wb.getSheetAt(0);
int count = sheet.getLastRowNum();
if(maxCount == 0){
maxCount = DEFAULT_COUNT;
}
if(count > maxCount){
throw new Exception("匯入失敗,excel資料控制在"+maxCount+"條之內!");
}
//遍歷excel表格並將每一行中的資料轉換成物件
if(startLine < 0){
startLine = DEFAULT_START_LINE;
}
for(int i=startLine;i<=count;i++){
Row row = sheet.getRow(i);
if(row==null){
continue;
}
T obj = convertLineToObj(clazz,row);
if(obj==null){
continue;
}
list.add(obj);
}
}
return list;
}
//行遍歷
private static <T> T convertLineToObj(Class<T> clazz, Row row) throws Exception {
T obj = clazz.newInstance();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields){
ExcelImport annotation = field.getAnnotation(ExcelImport.class);
if(annotation!=null && row.getLastCellNum() >= annotation.columnIndex()){
//每行對應的單元格遍歷
Cell cell = row.getCell(annotation.columnIndex());
if(cell==null)
throw new Exception("請使用正確的excel模板");
field.setAccessible(true);
field.set(obj,getCellValue(cell));
}
}
return obj;
}
private static Object getCellValue(Cell cell) {
if(cell.getCellType() == Cell.CELL_TYPE_BOOLEAN){
return String.valueOf(cell.getBooleanCellValue());
}else if(cell.getCellType()==Cell.CELL_TYPE_NUMERIC){
DecimalFormat df = new DecimalFormat("0.00");
String str = df.format(cell.getNumericCellValue());
return str;
}
return String.valueOf(cell.getStringCellValue());
}
public static void main(String[] args) {
try {
FileInputStream in = new FileInputStream("/Users/vobile_lzl/Downloads/tvids(2).xlsx");
// List<TvIdPresent> list = convertSheetToList(in, TvIdPresent.class,false,1);
// System.out.println("list = " + list);
} catch (Exception e) {
e.printStackTrace();
}
}
}
註解類()
該類主要用來識別excel欄位中對應那個javaBean的屬性。
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public @interface ExcelImport {
int columnIndex() default 0;
}
- 例子
public class ShopResourceExcelBo {
@ExcelImport(columnIndex = 0)
private String resourceId;
@ExcelImport(columnIndex = 1)
private String resourceName;
@ExcelImport(columnIndex = 2)
private String priceStr;
@ExcelImport(columnIndex = 3)
private String inventoryNumStr;
}
...省去set和get方法
呼叫方法
List<ShopResourceExcelBo> excelList = ImportExcelUtil.convertSheetToList(inputStream,
ShopResourceExcelBo.class,isExcel2003,1,500);
匯出Excel
將List集合中的物件轉換過成excel單元格資料
- 同樣是利用poi的匯出功能來實現。
- 利用註解來說明javaBean的屬性對應excel的單元格資訊。
- 利用java反射將註解類的屬性描述寫入到excel的頭資訊上。
- 利用java反射將註解類中的屬性值寫入到excel對應的單元格。
程式碼實現
public class ExportExcelUtil {
private final Logger logger = LoggerFactory.getLogger(ExportExcelUtil.class);
private OutputStream outputStream;
private Workbook workbook;
private HSSFSheet sheet;
private int index;
public ExportExcelUtil(String fileName){
try {
this.init(new FileOutputStream(fileName));
} catch (FileNotFoundException e) {
logger.error("匯出excel出錯");
e.printStackTrace();
}
}
public ExportExcelUtil(OutputStream outputStream){
try {
this.init(outputStream);
} catch (Exception e) {
logger.error("匯出excel出錯");
e.printStackTrace();
}
}
private void init(OutputStream fileOutputStream) {
this.outputStream = fileOutputStream;
this.workbook = new HSSFWorkbook();
this.index = 0;
}
public ExportExcelUtil writeHead(Class<?> tClass){
if (tClass==null){
return this;
}
List<String> list = new ArrayList<>();
for (Field filed : getFields(tClass)) {
ExcelExport excelExport = filed.getAnnotation(ExcelExport.class);
list.add(excelExport.columnName());
}
createData(list);
return this;
}
/**
* 獲取帶有ExcelExport註解的屬性
* @param tClass
* @return
*/
private List<Field> getFields(Class<?> tClass){
Field[] fields = tClass.getDeclaredFields();
List<Field> list = new ArrayList<>(fields.length);
for (Field f: fields) { //遍歷tClass中的屬性
if(f.isAnnotationPresent(ExcelExport.class)){ //有ExcelExport註解的資訊屬性保留
list.add(f);
}
}
return list;
}
/**
* 行列填充資料
* @param list
*/
private void createData(List<String> list) {
if(sheet == null){
sheet = (HSSFSheet) workbook.createSheet();
}
HSSFRow row = sheet.createRow(index++);
HSSFCell[] cells = new HSSFCell[list.size()];
for(int i=0;i<cells.length;i++) {
cells[i] = row.createCell(i);
cells[i].setCellValue(list.get(i));
}
}
public <T> ExportExcelUtil writeList(List<T> list){
if(list!=null && list.size()>0){
for ( Object obj: list) {
writeObject(obj);
}
}
return this;
}
private void writeObject(Object obj) {
Class clazz = obj.getClass();
List<String> list = new ArrayList<>();
for (Field f: getFields(clazz)) {
f.setAccessible(true);
try {
Object o = f.get(obj);
if(o instanceof Date){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
list.add(sdf.format(o));
}else if(o instanceof BigDecimal){
list.add(String.valueOf(((BigDecimal) o).setScale(2,BigDecimal.ROUND_CEILING)));
}else{
list.add(String.valueOf(o));
}
} catch (IllegalAccessException e) {
e.printStackTrace();
logger.error("格式化obj失敗");
}
}
if(!list.isEmpty()){
createData(list);
}
}
public void exportData(){
try {
workbook.write(outputStream);
} catch (IOException e) {
e.printStackTrace();
logger.error("建立excel失敗");
}
}
}
註解類
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public @interface ExcelExport {
String columnName() default "";
}
- 例子
public class OperationRecordVO{
@ExcelExport(columnName = "使用者名稱")
private String username;
@ExcelExport(columnName = "角色")
private String roleName;
@ExcelExport(columnName = "IP地址")
private String ip;
@ExcelExport(columnName = "操作內容")
private String context;
private Integer type;
@ExcelExport(columnName = "操作型別")
private String typeStr;
private String objectType;
private String objectId;
@ExcelExport(columnName = "操作時間")
@JsonSerialize(converter = JacksonDateConverter.BacklashDateTimeConverter.class)
private Date createTime;
}
...省去get和set方法
//呼叫例項
public void exportRecords(String startTime,String endTime,HttpServletResponse response){
List<OperationRecordVO> list = operationRecordService.exportRecordsByDate(startTime,endTime);
//匯出excel
String fileName = "操作日誌.xls";
try {
response.setContentType("application/octet-stream;");
response.setHeader("Content-disposition",
"attachment; filename=" + new String(fileName.getBytes("UTF-8"), "iso8859-1"));
ExcelExportUtil excelExportUtil = new ExcelExportUtil(response.getOutputStream());
//excel第一列表頭資訊
excelExportUtil.writeHeader(OperationRecordVO.class);
//寫入每一行資訊
excelExportUtil.writeObjects(list);
excelExportUtil.exportData();
} catch (IOException e) {
logger.error("匯出excel失敗...");
e.printStackTrace();
}
}