最近項目升級,需要在excel導出時根據列名,有候選碼值的要求下拉展示,所以對這塊記錄一下。
使用的POI版本為3.17。導出時添加下拉框分兩種情況,以下拉框字符數是否超過255區分,兩種情況的參考代碼如下:
一、簡單類型的下拉框,碼值不超過255個字符時使用。
1 package test; 2 3 import org.apache.poi.hssf.usermodel.*; 4 import org.apache.poi.ss.util.CellRangeAddressList; 5 import org.junit.Test; 6 7 import java.io.FileOutputStream; 8 import java.io.IOException; 9 import java.util.HashMap; 10 import java.util.Map; 11 12 /** 13 * @ClassName test2 14 * @Description: TODO 15 * @Author zyf 16 * @Date 2020/8/4 17 * @Version V1.0 18 **/ 19 public class test2 { 20 21 @Test 22 public void test() throws IOException { 23 HSSFWorkbook hssfWorkbook = new HSSFWorkbook(); 24 HSSFSheet sheet = hssfWorkbook.createSheet(); 25 HSSFRow row = sheet.createRow(0); 26 row.createCell(0).setCellValue("名稱"); 27 row.createCell(1).setCellValue("類型"); 28 String col = "JGLX"; //機構類型 29 Map<String, String> boxMap = new HashMap<>(); 30 boxMap.put("JGLX", "1類型,2類型,3類型"); 31 //指定將下拉框添加至1-10行,0-0列。即第一列的第2到11行 32 HSSFDataValidation dataValidation = createBox(col, boxMap , 1 , 10 , 0 , 0); 33 if(dataValidation != null) { 34 sheet.addValidationData(dataValidation); 35 } 36 FileOutputStream out = new FileOutputStream("C:\\Users\\yf\\Desktop\\test1.xls"); 37 hssfWorkbook.write(out); 38 out.close(); 39 } 40 41 /** 42 * excel導出,有碼值的數據使用下拉框展示。 43 * @param col 列名 44 * @param boxMap 碼值集合 45 * @param firstRow 插入下拉框開始行號 46 * @param lastRow 插入下拉框結束行號 47 * @param firstCol 插入下拉框開始列號 48 * @param lastCol 插入下拉框結束行號 49 * @return 50 */ 51 public HSSFDataValidation createBox(String col, Map<String , String> boxMap , int firstRow, int lastRow, int firstCol, int lastCol) { 52 HSSFDataValidation dataValidation = null; 53 //查詢碼值表 54 String cols = ""; 55 if(null != boxMap.get(col)) { 56 cols = boxMap.get(col); 57 } 58 //設置下拉框 59 if(cols.length() > 0 && null != cols) { 60 String str[] = cols.split(","); 61 //指定0-9行,0-0列為下拉框 62 CellRangeAddressList cas = new CellRangeAddressList(firstRow , lastRow , firstCol , lastCol); 63 //創建下拉數據列 64 DVConstraint dvConstraint = DVConstraint.createExplicitListConstraint(str); 65 //將下拉數據放入下拉框 66 dataValidation = new HSSFDataValidation(cas, dvConstraint); 67 } 68 return dataValidation; 69 } 70 71 72 }
二、復雜類型下拉框、碼值超過255個字符 1 package test;
2 3 import org.apache.poi.hssf.usermodel.*; 4 import org.apache.poi.ss.usermodel.Name; 5 import org.apache.poi.ss.util.CellRangeAddressList; 6 import org.junit.Test; 7 8 import java.io.FileOutputStream; 9 import java.io.IOException; 10 import java.util.HashMap; 11 import java.util.List; 12 import java.util.Map; 13 14 /** 15 * @ClassName test3 16 * @Description: TODO 17 * @Author zyf 18 * @Date 2020/8/4 19 * @Version V1.0 20 **/ 21 public class test3 { 22 23 @Test 24 public void test() throws IOException { 25 HSSFWorkbook hssfWorkbook = new HSSFWorkbook(); 26 HSSFSheet sheet = hssfWorkbook.createSheet(); 27 HSSFRow row = sheet.createRow(0); 28 row.createCell(0).setCellValue("名稱"); 29 row.createCell(1).setCellValue("類型"); 30 String col = "JGLX"; //機構類型 31 Map<String, String> boxMap = new HashMap<>(); 32 boxMap.put("JGLX", "1類型,2類型,3類型"); 33 int i =0; 34 HSSFDataValidation dataValidation = createBox1(hssfWorkbook , col, boxMap , 10 , i , 0); 35 if(dataValidation != null) { 36 sheet.addValidationData(dataValidation); 37 } 38 FileOutputStream out = new FileOutputStream("C:\\Users\\yf\\Desktop\\test22.xls"); 39 hssfWorkbook.write(out); 40 out.close(); 41 } 42 /** 43 * excel導出,有碼值的數據使用下拉框展示。解決下拉框最多255個字符的問題。 44 * 原理為新建一個隱藏狀態的sheet頁,用來存儲下拉框的值。 45 * @param wb 工作簿 HSSFWorkbook 46 * @param col 當前列名 47 * @param boxMap 碼值集合 48 * @param rows 正常sheet頁數據,用來指定哪些行需要添加下拉框 49 * @param i 多個碼值需要添加下拉,隱藏狀態的sheet頁名稱不能重復,添加i值區分。 50 * @param colToIndex 用來指定哪些列需要添加下拉框 51 * @return dataValidation 52 */ 53 public HSSFDataValidation createBox1(HSSFWorkbook wb, String col, Map<String , String> boxMap, int rows, int i, int colToIndex) { 54 HSSFDataValidation dataValidation = null; 55 String cols = ""; 56 //查詢碼值集合,獲取當前列的碼值。 57 if(null != boxMap.get(col)) { 58 cols = boxMap.get(col); 59 } 60 //新建隱藏狀態的sheet,用來存儲碼值。 61 if(cols.length() > 0 && null != cols) { 62 String str[] = cols.split(","); 63 //創建sheet頁 64 HSSFSheet sheet = wb.createSheet("hidden"+i); 65 //向創建的sheet頁添加碼值數據。 66 for (int i1 = 0; i1 < str.length; i1++) { 67 HSSFRow row = sheet.createRow(i1); 68 HSSFCell cell = row.createCell((int) 0); 69 cell.setCellValue(str[i1]); 70 } 71 //將碼值sheet頁做成excel公式 72 Name namedCell = wb.createName(); 73 namedCell.setNameName("hidden"+i); 74 namedCell.setRefersToFormula("hidden"+i+"!$A$1:$A$" + str.length); 75 //確定要在哪些單元格生成下拉框 76 DVConstraint dvConstraint = DVConstraint.createFormulaListConstraint("hidden"+i); 77 CellRangeAddressList regions = new CellRangeAddressList(1 , rows , colToIndex , colToIndex); 78 dataValidation = new HSSFDataValidation(regions, dvConstraint); 79 //隱藏碼值sheet頁 80 int sheetNum = wb.getNumberOfSheets();
for(int n=1; n<sheetNum; n++) {
wb.setSheetHidden(n, true);
}
81 } 82 return dataValidation; 83 } 84 }