Springboot 之 使用POI操作excel

为了方便地使用poi操作excel,在这里,使用类BubbleSheet对Poi中的Sheet进行封装,BubbleSheet类如下所示:

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;

import java.util.ArrayList;
import java.util.List;

public class BubbleSheet {

    private Sheet sheet;

    private Row nowRow;

    private Integer nowRowNo;

    private HSSFWorkbook wb;

    private List<HSSFCellStyle> cellStylesList = new ArrayList<HSSFCellStyle>();

    BubbleSheet(HSSFWorkbook wb) {
        this.wb = wb;
        this.sheet = wb.createSheet();
        createCellStyleList();
        nowRowNo = -1;
        setNowRowWithRowNo(0);
    }

    private HSSFCellStyle createCellStyle(int poiColorIndex, int r, int g, int b) {
        HSSFCellStyle cellStyle =  wb.createCellStyle();

        cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);

        cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框
        cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN); //左边框
        cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN); //上边框
        cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN); //右边框

        HSSFPalette palette = wb.getCustomPalette();
        palette.setColorAtIndex((short)poiColorIndex, (byte) r, (byte) g, (byte) b);
        cellStyle.setFillForegroundColor((short)poiColorIndex);
        cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

        return cellStyle;
    }

    private void createCellStyleList() {
        cellStylesList.add(createCellStyle(HSSFColor.LIME.index, 255, 255, 255)); // 默认的白色
        cellStylesList.add(createCellStyle(HSSFColor.BLUE.index, 211, 209, 207));  // 内容浅灰色
        cellStylesList.add(createCellStyle(HSSFColor.GREEN.index, 186, 210, 170)); // 表头浅绿色
    }

    public void mergeCells(Integer firstRow, Integer lastRow, Integer firstCol, Integer lastCol, String content, int colorIndex) {
        CellRangeAddress cra = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
        //在sheet里增加合并单元格
        sheet.addMergedRegion(cra);
        Cell cell_1 = nowRow.createCell(firstCol); // 选择第一行的第一个单元格,因为位置在这个位置,所以设置的是合并的单元格
        cell_1.setCellStyle(cellStylesList.get(colorIndex));
        // 设置单元格的内容
        cell_1.setCellValue(content);

        // 设置合并单元格的边框
        RegionUtil.setBorderBottom(HSSFCellStyle.BORDER_THIN, cra, sheet, wb); // 下边框
        RegionUtil.setBorderLeft(HSSFCellStyle.BORDER_THIN, cra, sheet, wb); // 左边框
        RegionUtil.setBorderRight(HSSFCellStyle.BORDER_THIN, cra, sheet, wb); // 有边框
        RegionUtil.setBorderTop(HSSFCellStyle.BORDER_THIN, cra, sheet, wb); // 上边框
    }

    public void setLineValues(Integer col, String[] titleNames, int colorIndex) {
        for(String stp: titleNames) {
            Cell ctp = nowRow.createCell(col ++);
            ctp.setCellValue(stp);
            ctp.setCellStyle(cellStylesList.get(colorIndex));
        }
    }

    public void setNowRowWithRowNo(Integer rowNo) {
        // 这里的逻辑感觉很奇怪,主要是在getRow、createRow以及样式设置上的相互作用的结果。
        if(rowNo == null) rowNo = 0 ;
        if(nowRowNo.equals(rowNo)) { // 如果是合并单元格行后面的创建单元时,不需要重新生成这行了。
            return ;
        }
        Row row = sheet.getRow(rowNo); // 使用这个的原因是:需要设置合并单元格的外边框样式,如果不用这个会出错。
        if(row == null){
            row = sheet.createRow(rowNo);
        }
        nowRowNo = rowNo;
        setNowRow(row);
    }

    private void setNowRow(Row nowRow) {
        this.nowRow = nowRow;
    }

    public void createFreezePane(int startRowNo, int endRowNo, int startColNo, int endColNo) {
        sheet.createFreezePane( startRowNo, endRowNo, startColNo, endColNo);
    }
}

接下来使用BubbleSheet方便操作表格的例子如下:

import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;

public class bubbleSheet_ex {

    static final  private String[] titleNames = {
            "广告位", "月度", "项目名称", "预定量",
            "预计本月金额", "直客公司",
            "所属区域", "对应销售", "媒介", "当月比例"};

    public static int stepHigh = 0;

    public static void main(String[] args) {

        HSSFWorkbook wb =  new HSSFWorkbook();
        BubbleSheet bs = new BubbleSheet(wb);
        bs.setNowRowWithRowNo(0); // 设置要操作哪一行
        bs.mergeCells(0, 0, 0, 1, titleNames[0], 0); // 设置第一行第一个标题
        final String[] titleNames_temp = Arrays.copyOfRange(titleNames, 1, titleNames.length);

        bs.setNowRowWithRowNo(0); // 设置要操作哪一行
        bs.setLineValues(2, titleNames_temp, 0); // 设置第一行除第一个以外的标题

        stepHigh = 10;
        int firstRow_temp = 1;
        bs.setNowRowWithRowNo(firstRow_temp); // 设置要操作哪一行
        bs.mergeCells(firstRow_temp, firstRow_temp + stepHigh, 0, 1, "模块1", 1);

        firstRow_temp = 13;
        bs.setNowRowWithRowNo(firstRow_temp); // 设置要操作哪一行
        bs.mergeCells(firstRow_temp, firstRow_temp + stepHigh, 0, 1, "模块2", 2);

        saveexcel(wb, "e:/test_bs.xls");
    }

    private static void saveexcel(HSSFWorkbook wb, String filename) {
        // 保存文件
        File file = new File(filename);
        try {
            file.createNewFile(); // 创建文件
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            FileOutputStream fos = new FileOutputStream(file);
            try {
                wb.write(fos);
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

从例子中可以看出,BubbleSheet经常用的方法有mergeCells以及setLineValues,从名字可以看出两者的用途,在使用这两个方法之前,都要用setNowRowWithRowNo方法,用来指明是要操作哪一行的。

在我的工作中检验发现,BubbleSheet是可靠的,且在操作表格时非常便捷。

猜你喜欢

转载自blog.csdn.net/o1101574955/article/details/80228294