Упрощенный импорт и экспорт Excel на основе пакета POI ExcelUtil

Java

poi
poi

Примечание

Эта статья представляет собой простую инкапсуляцию с использованием org.apache.poi, которая подходит для большинства функций импорта и экспорта Excel. В процессе можно использовать рефлексию.Если есть ученики с крайним обсессивно-компульсивным расстройством в отношении успеваемости, просто посмотрите.

последовательность

Так как poi сам по себе является лишь набором инструментов для офисного ПО типа excel, то при импорте и экспорте какого-то обычного excel необходимо делать упрощенную инкапсуляцию для упрощения связывания кода.

1. Статус-кво

Я испытал инкапсуляцию кода нескольких компаний, и импорт и экспорт обычно существуют в следующих ситуациях.

1.1 Импорт

  1. Передайте адрес файла, верните объект Sheet, выполните цикл по бизнес-коду, выполните соответствующее преобразование типов, бизнес-обработку (инфраструктура кода в 2000 г.)
  2. Передайте адрес файла, верните объект List и напрямую выполните внешнее принудительное преобразование.
  3. Передать адрес файла, вернуть объект List, внешне преобразовать строковый объект в соответствующий тип

Резюме: Если есть только вышеперечисленный выбор, то я больше склоняюсь ко второму, ведь он очень дружелюбен к внешнему миру

1.2 Экспорт

  1. Пройдите лист инкапсуляции непосредственно в логическом коде и передайте его в метод генерации файла (фреймворк кода в 2000 году).
  2. Сначала выполните цикл по объекту List, преобразуйте его в объект List>, передайте fieldName в метод, сгенерированный упакованным excel, и используйте метод map.get() внутри для работы
  3. Напрямую передайте объект List с fieldName в метод, сгенерированный инкапсулированным excel, преобразуйте объект Model в JSONObject внутренне, а затем используйте метод jsonObj.get() для работы
  4. Сначала преобразуйте список в JSONArray, передайте fieldName в метод, сгенерированный инкапсулированным excel, внутренне преобразуйте объект модели в JSONObject, а затем используйте метод jsonObj.get() для работы. (При использовании этого подхода, согласно анализу, он должен быть выполнен для выполнения jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor("гггг-ММ-дд ЧЧ:мм:сс")); Эта строка кода может быть для решения проблема формата типа даты)

Резюме: Если есть только вышеперечисленные варианты, то я больше склоняюсь к третьему, который проходит только один раз и внешне не обрабатывается. Однако, согласно четвертому моду, в третьем режиме все еще будет проблема с форматом даты, и мы разберем, как с этим бороться позже.

2. Импорт

2.1 Определение метода

/**
* excel导入
* @param keys		字段名称数组,如  ["id", "name", ... ]
* @param filePath	文件物理地址
* @return 
* @author yzChen
* @date 2016年12月18日 下午2:46:51
*/
public static List<Map<String, Object>> imp(String filePath, String[] keys)
    throws Exception {}

2.2 Модуль обработки циклов

// 遍历该行所有列
for (short j = 0; j < cols; j++) {
    cell = row.getCell(j);
    if(null == cell) continue;	// 为空时,下一列
    
    // 根据poi返回的类型,做相应的get处理
    if(Cell.CELL_TYPE_STRING == cell.getCellType()) {
        value = cell.getStringCellValue();
    } else if(Cell.CELL_TYPE_NUMERIC == cell.getCellType()) {
        value = cell.getNumericCellValue();
        
        // 由于日期类型格式也被认为是数值型,此处判断是否是日期的格式,若时,则读取为日期类型
        if(cell.getCellStyle().getDataFormat() > 0)  {
            value = cell.getDateCellValue();
        }
    } else if(Cell.CELL_TYPE_BOOLEAN == cell.getCellType()) {
        value = cell.getBooleanCellValue();
    } else if(Cell.CELL_TYPE_BLANK == cell.getCellType()) {
        value = cell.getDateCellValue();
    } else {
        throw new Exception("At row: %s, col: %s, can not discriminate type!");
    }
    
    map.put(keys[j], value);
}

2.3 Использование

String filePath = "E:/order.xls";
String[] keys = new String[]{"id","brand"};

List<Map<String, Object>> impList;
try {
    impList = ExcelUtil.imp(filePath, keys);
    
    for (Map<String, Object> map : impList) {
        System.out.println(map.get("brand"));
    }
} catch (Exception e) {
    e.printStackTrace();
}

2.4 Анализ

  1. Запись должна передавать только имя файла и ключ, который необходимо прочитать извне.
  2. Для внутренней обработки соответствующая обработка была выполнена для числовых типов, дат и строковых типов, а внешне соответствующий тип может быть принудительно принудительно задан.

3. Экспорт

3.1 Определение метода

/**
* excel导出
* @param fileNamePath	导出的文件名称
* @param sheetName	导出的sheet名称
* @param list		数据集合
* @param titles		第一行表头
* @param fieldNames	字段名称数组
* @return
* @throws Exception    
* @author yzChen
* @date 2017年5月6日 下午3:53:47
*/
public static <T> File export(String fileNamePath, String sheetName, 
    List<T> list, String[] titles, String[] fieldNames) throws Exception {}

3.2 Модуль обработки циклов

// 遍历生成数据行,通过反射获取字段的get方法
for (int i = 0; i < list.size(); i++) {
    t = list.get(i);
    HSSFRow row = sheet.createRow(i+1);
    Class<? extends Object> clazz = t.getClass();
    for(int j = 0; j < fieldNames.length; j++){
        methodName = "get" + capitalize(fieldNames[j]);
        try {
            method = clazz.getDeclaredMethod(methodName);
        } catch (java.lang.NoSuchMethodException e) {	//	不存在该方法,查看父类是否存在。此处只支持一级父类,若想支持更多,建议使用while循环
            if(null != clazz.getSuperclass()) {
                method = clazz.getSuperclass().getDeclaredMethod(methodName);
            }
        }
        if(null == method) {
            throw new Exception(clazz.getName() + " don't have menthod --> " + methodName);
        }
        ret = null == method.invoke(t) ? null : method.invoke(t) + "";
        setCellGBKValue(row.createCell(j), ret + "");
    }
}

3.3 Использование

String[] titles = new String[]{"Id", "Brand"};
String[] fieldNames = new String[]{"id", "brand"};
List<Order> expList = new ArrayList<Order>();
Order order = new Order();
order.setId(1L);
order.setBrand("第三方手动阀");
expList.add(order);
order = new Order();
order.setId(2L);
order.setBrand("scsdsad");
expList.add(order);

String fileNamePath = "E:/order.xls";
try {
    ExcelUtil.export(fileNamePath, "订单", expList, titles, fieldNames);
} catch (Exception e) {
    e.printStackTrace();
}

3.4 Резюме

  1. Запись в основном должна передаваться в сбор данных списка, а также имя поля fieldNames.
  2. Внутренняя обработка заключается в непосредственном получении возвращаемого значения метода get посредством отражения и преобразовании его в строку для экспорта.
  3. Чтобы быть совместимым с дизайном наследования некоторых общих полей родительского класса, добавляется слой чтения методов родительского класса.

4. Об обработке экспорта типа даты

1.1 Экспорт содержимого указанного формата из поля даты

  1. Рекомендуется добавить поле расширения в класс Model и инкапсулировать метод get, а содержимое предназначено только для преобразования исходного поля.При экспорте fieldName может передать поле расширения. Такой как createTime, пример выглядит следующим образом:
private Date createTime;
private String createTimeStr;	// 扩展字段

public Date getCreateTime() {
    return createTime;
}

public void setCreateTime(Date createTime) {
    this.createTime = createTime;
}

public String getCreateTimeStr() {
    createTimeStr = DateUtil.formatDatetime(this.createTime);
    return createTimeStr;
}

My Blog

blog.guijianpan.com

Обмен технологиями