Springboot 之 使用POI操作excel
阿新 • • 發佈:2019-02-18
為了方便地使用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是可靠的,且在操作表格時非常便捷。