因为公司需要利用poi 进行自定义的导出,乘此了解一下poi的一些常用操作

client 端

import com.alibaba.excel.metadata.BaseRowModel;
import com.hiberate.huijpa.pojo.EmpExcelModel;
import com.hiberate.huijpa.util.ReflectUtil;
import org.apache.poi.ss.usermodel.Workbook;
import org.junit.Test;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author liyhu
 * @date 2019年09月28日
 */
public class PoiModelClient {
    public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        String sheetName="one";
        List<BaseRowModel> data=new ArrayList<>();
        for (int i = 0; i < 9; i++) {
            EmpExcelModel model=new EmpExcelModel();
            model.setMobile("mobile"+i);
            model.setCardPassword("pwd"+i);
            model.setCardSn("sn"+i);
            model.setCardNo("no"+i);
            model.setFreezeStatus("正常");
            data.add(model);
        }
        Workbook wb = ExcelUtil.createExcel(sheetName, data);
        try (FileOutputStream os = new FileOutputStream("D:\\a.xlsx")){
            wb.write(os);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("ok");

    }
}

工具类

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.BaseRowModel;
import com.hiberate.huijpa.util.ReflectUtil;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author liyhu
 * @date 2019年09月28日
 */
public class ExcelUtil {

    private static short text;
    private static Font blodFont ;// 粗字
    private static Font redFont; // 红字
    private static Workbook globalWorkBook =new XSSFWorkbook();
//  匹配这种格式  *状态[正常/立即冻结/售完冻结]
    private static Pattern pullDownPattern = Pattern.compile("[\\u4e00-\\u9fa5]+\\[([\\u4e00-\\u9fa5]+/[\\u4e00-\\u9fa5|/]+)]$");
    static {
        DataFormat dataFormat = globalWorkBook.createDataFormat();//创建格式化对象
        text=dataFormat.getFormat("TEXT");

        blodFont= globalWorkBook.createFont();
        blodFont.setBold(true);// 加粗
        blodFont.setFontName("宋体");
        blodFont.setFontHeightInPoints((short) 14);// 14号字体

        redFont = globalWorkBook.createFont();
        redFont.setBold(true);
        redFont.setFontName("宋体");
        redFont.setColor(Font.COLOR_RED);
    }

    /**
     * 这里的 workbook 不能用全局的 workbook
     * @param workbook
     * @return
     */
    private static CellStyle crateTitleCellStyle(Workbook workbook){
        CellStyle titleStyle = workbook.createCellStyle();        //标题样式
        titleStyle.setAlignment(HorizontalAlignment.CENTER);
        titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        titleStyle.setBorderBottom(BorderStyle.THIN);
        titleStyle.setBorderRight(BorderStyle.THIN);

        titleStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        return titleStyle;
    }
    /**
     * 创建 1,2 行
     * @param sheet
     * @param colNum
     */
    private static void setOneTwoTitle(Workbook workbook , Sheet sheet , int colNum,String firtRowVal){
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, colNum - 1));// 合并单元格
        Row firstTitleRow = sheet.createRow(0);
        Cell firstTitleCell = firstTitleRow.createCell(0);
        firstTitleCell.setCellValue(firtRowVal);

        CellStyle firstCellStyle = createFirstRowStyle(workbook);
        firstTitleCell.setCellStyle(firstCellStyle);

        sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, colNum - 1));
        Row secondTitleRow = sheet.createRow(1);
        Cell secondTitleCell = secondTitleRow.createCell(0);// 第二行样式
        secondTitleCell.setCellValue("导入人:");

        CellStyle secondCellStyle = createSecondRowStyle(workbook);
        secondTitleCell.setCellStyle(secondCellStyle);
    }

    /**
     * 创建第一行样式
     * @param workbook
     * @return
     */
    private static CellStyle createFirstRowStyle(Workbook workbook){
        CellStyle firstCellStyle = workbook.createCellStyle();// 第一行样式
        firstCellStyle.setAlignment(HorizontalAlignment.CENTER);
        firstCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        firstCellStyle.setFont(blodFont);
        return firstCellStyle;
    }
    /**
     * 创建第二行样式
     * @param workbook
     * @return
     */
    private static CellStyle createSecondRowStyle(Workbook workbook){
        CellStyle secondCellStyle = workbook.createCellStyle();
        secondCellStyle.setAlignment(HorizontalAlignment.LEFT);
        secondCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        secondCellStyle.setFont(blodFont);
        return secondCellStyle;
    }

    /**
     * 创建标题
     * @param workbook
     * @param sheet
     * @param beanMap
     * @param colWidthMap
     */
    private static void setHeader(Workbook workbook, Sheet sheet, Map<String, Object> beanMap, BaseRowModel model, Map<Integer, Integer> colWidthMap, int startRow){
        Row titleRow = sheet.createRow(startRow);
        CellStyle textStyle = workbook.createCellStyle();        //标题样式
        textStyle.setDataFormat(text);

        //这里不能和类里的font公用
        Font blodFont = workbook.createFont();
        blodFont.setBold(true);
        blodFont.setFontName("宋体");
        blodFont.setFontHeightInPoints((short) 14);


        CellStyle titleStyle= crateTitleCellStyle(workbook);
        titleStyle.setFont(blodFont);

        Field[] fields = model.getClass().getDeclaredFields();
        Map<String, Field> fieldMap = Arrays.stream(fields).collect(Collectors.toMap(Field::getName, f -> f));

        int index = 0;
        for (Map.Entry<String, Object> header : beanMap.entrySet()) {
            Cell cell = titleRow.createCell(index);
            cell.setCellStyle(titleStyle);
            String fieldName = header.getKey();
            Field field = fieldMap.get(fieldName);
            String excelPropertyVal = getExcelPropertyVal(field);

            Matcher matcher = pullDownPattern.matcher(excelPropertyVal);
            if(matcher.find()){// 创建该列的下拉
                String[] subjects  = matcher.group(1).split("/");
                DataValidationHelper helper = sheet.getDataValidationHelper();
                DataValidationConstraint constraint = helper.createExplicitListConstraint(subjects);
                CellRangeAddressList  addressList = new CellRangeAddressList(startRow + 1, startRow+50, index, index);
                DataValidation dataValidation = helper.createValidation(constraint, addressList);
                sheet.addValidationData(dataValidation);
            }

            setColWidth(colWidthMap,excelPropertyVal,index,true);
            RichTextString richTextString = new XSSFRichTextString(excelPropertyVal);
            richTextString.applyFont(blodFont);
            if (richTextString.getString().startsWith("*")) {
                richTextString.applyFont(0, 1, redFont);
            }
            cell.setCellValue(richTextString);
            sheet.setDefaultColumnStyle(index, textStyle);
            index++;
        }
    }

    private static void setColWidth(Map<Integer, Integer> colWidthMap, String val, int index, boolean isHeader){
        int length = val.length();
        Integer defaultColWidth = colWidthMap.get(index);
        if (length > defaultColWidth) {
            if(isHeader){// 标题则是字数的两倍
                length *= 2;
            }
            colWidthMap.put(index, length );
        }
    }

    /**
     * 得到 @ExcelProperty 注解的值
     * @param field
     * @return
     */
    public static String getExcelPropertyVal(Field field){
        ExcelProperty annotation = field.getAnnotation(ExcelProperty.class);
        if(annotation == null){
            return null;
        }
        return annotation.value()[0];
    }

    /**
     * 这里的 workbook 不能用全局的 workbook <br/>
     * 获取数据单元格样式
     * @return
     * @param workbook
     */
    private static CellStyle createDataCellStyle(Workbook workbook){
        CellStyle dataStyle = workbook.createCellStyle();
        dataStyle.setAlignment(HorizontalAlignment.CENTER);
        dataStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        dataStyle.setDataFormat(text);
        return dataStyle;
    }

    /**
     * 设置单元格数据
     * @param sheet
     * @param dataMapList
     * @param colWidthMap
     * @param startRow
     */
    private static void setData(Workbook workbook, Sheet sheet, List<Map<String, Object>> dataMapList, Map<Integer, Integer> colWidthMap, int startRow){
        CellStyle dataStyle= createDataCellStyle(workbook);
        int rowIndex = 0;
        for (Map<String, Object> beanMap : dataMapList) {
            Row row = sheet.createRow(rowIndex + startRow);
            int colIndex = 0;
            for (Map.Entry<String, Object> entry : beanMap.entrySet()) {
                Cell cell = row.createCell(colIndex);
                String valString = entry.getValue().toString();
                cell.setCellValue(valString);
                cell.setCellStyle(dataStyle);

                setColWidth(colWidthMap,valString,colIndex, true);
                colIndex++;
            }
            rowIndex++;
        }
    }

    public static Workbook createExcel(String sheetName, List<BaseRowModel> data) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        List<Map<String, Object>> dataMapList = new ArrayList<>();
        for (BaseRowModel model : data) {
            Map<String, Object> map = ReflectUtil.beanToMap(model);
            map.remove("cellStyleMap");//不需要这个属性
            dataMapList.add(map);
        }
        Map<String, Object> firstBeanMap = dataMapList.get(0);
        int colNum = firstBeanMap.size();// 列的数量
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet(sheetName);
        sheet.setDefaultRowHeight((short) (2 * 256));//设置默认行高

        setOneTwoTitle(  workbook ,  sheet , colNum,"员工");

        Map<Integer, Integer> colWidthMap = new HashMap<>();
        for (int i = 0; i < colNum; i++) {// 设置默认列宽
            colWidthMap.put(i, 14);
        }
        setHeader(workbook,sheet,firstBeanMap,data.get(0),colWidthMap,2);

       setData(workbook,sheet,dataMapList,colWidthMap,3);

        for (Map.Entry<Integer, Integer> entry : colWidthMap.entrySet()) {
            sheet.setColumnWidth(entry.getKey(), entry.getValue() * 256);//设置每列宽度
        }
        return workbook;
    }


    public static TreeMap<Integer,String>  getSortMap(Class<?> clazz){
        TreeMap<Integer,String> treeMap=new TreeMap<>();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
            if(excelProperty == null){
                continue;
            }
            treeMap.put(excelProperty.index(),field.getName());
        }
        return treeMap;
    }

}

 实体转换工具类

 

import com.alibaba.excel.annotation.ExcelProperty;
import org.apache.commons.beanutils.PropertyUtilsBean;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * @author liyhu
 * @date 2019年08月27日
 */
public class ReflectUtil {
    public static <T>T mapToProperties(Map<String,Object> map,Class<T> tClass) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException {
        T t = tClass.newInstance();
        PropertyUtilsBean propertyUtilsBean = new PropertyUtilsBean();
        PropertyDescriptor[] descriptors = propertyUtilsBean.getPropertyDescriptors(t);
        for (PropertyDescriptor descriptor : descriptors) {
            String name = descriptor.getName();
            if("class".equals(name)){
                continue;
            }
            Object val = map.get(name);
            if(val != null){
                propertyUtilsBean.setProperty(t,name,val);
            }
        }
        return t;
    }
    public static Map<String,Object> commonBeanToMap(Object obj) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        PropertyUtilsBean propertyUtilsBean = new PropertyUtilsBean();
        PropertyDescriptor[] descriptors = propertyUtilsBean.getPropertyDescriptors(obj);
        Map<String,Object> resultMap=new HashMap<>(descriptors.length);
        for (PropertyDescriptor descriptor : descriptors) {
            String name = descriptor.getName();
            if("class".equals(name)){
                continue;
            }
            Object val = propertyUtilsBean.getNestedProperty(obj, name);
            if(val != null){
                resultMap.put(name,val);
            }
        }
        return resultMap;
    }

    public static Map<String,Object> beanToMap(Object obj) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, NoSuchFieldException {
        TreeMap<Integer,String> treeMap=new TreeMap<>();
        Class<?> aClass = obj.getClass();
        PropertyUtilsBean propertyUtilsBean = new PropertyUtilsBean();
        PropertyDescriptor[] descriptors = propertyUtilsBean.getPropertyDescriptors(obj);
        Map<String,Object> resultMap=new HashMap<>(descriptors.length);
        for (PropertyDescriptor descriptor : descriptors) {
            String name = descriptor.getName();
            if("class".equals(name)){
                continue;
            }
            Object val = propertyUtilsBean.getNestedProperty(obj, name);
            if(val != null){
                resultMap.put(name,val);
                if("cellStyleMap".equals(name)){
                    continue;
                }
                Field field = aClass.getDeclaredField(name);
                ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
                if(excelProperty != null){
                    treeMap.put(excelProperty.index(),name);
                }
            }
        }

        Map<String,Object> result=new LinkedHashMap<>();
        for (Map.Entry<Integer, String> entry : treeMap.entrySet()) {
            Object val = resultMap.get(entry.getValue());
            result.put(entry.getValue(),val);
        }

        return result;
    }



}

  

02-01 08:54