1. 程式人生 > >excel匯入匯出工具類

excel匯入匯出工具類

Excel匯入功能

匯入功能是將excel中的資料轉換成對應的javaBean。

實現思路

  1. 使用poi讀取excel表格
  2. 獲取每行表格中的單元格資訊,將單元格中的資料存入到對應的javaBean中。
  3. 寫一個註解類來標註javaBean中的那個屬性要與Excel中的資料進行對應。
  4. 運用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();
        }
    }