最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java使用Apache?POI在Excel中創(chuàng)建下拉列表

 更新時間:2026年03月23日 08:46:18   作者:Java小王子呀  
在業(yè)務(wù)系統(tǒng)中,我們經(jīng)常需要導(dǎo)出包含下拉選擇框的Excel模板,用于規(guī)范數(shù)據(jù)錄入,Apache?POI作為Java操作Office文檔的主流工具,提供了完善的數(shù)據(jù)驗證功能,本文將詳細介紹如何使用POI在Excel中創(chuàng)建下拉列表,感興趣的可以了解下

概述

在業(yè)務(wù)系統(tǒng)中,我們經(jīng)常需要導(dǎo)出包含下拉選擇框的Excel模板,用于規(guī)范數(shù)據(jù)錄入。Apache POI作為Java操作Office文檔的主流工具,提供了完善的數(shù)據(jù)驗證功能。本文將詳細介紹如何使用POI在Excel中創(chuàng)建下拉列表。

核心實現(xiàn)

1. 基礎(chǔ)依賴

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.3</version>
</dependency>

2. 單級下拉列表實現(xiàn)

public class ExcelDropdownDemo {
    
    public void createSingleDropdown() throws IOException {
        // 創(chuàng)建工作簿和工作表
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("數(shù)據(jù)錄入");
        
        // 定義下拉選項
        String[] options = {"待處理", "處理中", "已完成", "已關(guān)閉"};
        
        // 創(chuàng)建數(shù)據(jù)驗證助手
        DataValidationHelper helper = sheet.getDataValidationHelper();
        
        // 創(chuàng)建約束:從數(shù)組創(chuàng)建下拉列表
        DataValidationConstraint constraint = helper.createExplicitListConstraint(options);
        
        // 設(shè)置驗證范圍(例如在A2:A100創(chuàng)建下拉框)
        CellRangeAddressList addressList = new CellRangeAddressList(1, 99, 0, 0);
        
        // 創(chuàng)建數(shù)據(jù)驗證對象
        DataValidation validation = helper.createValidation(constraint, addressList);
        
        // 設(shè)置相關(guān)屬性
        validation.setShowErrorBox(true);
        validation.setErrorStyle(DataValidation.ErrorStyle.STOP);
        validation.createErrorBox("輸入錯誤", "請從下拉列表中選擇");
        
        // 應(yīng)用到工作表
        sheet.addValidationData(validation);
        
        // 寫入文件
        try (FileOutputStream fos = new FileOutputStream("template.xlsx")) {
            workbook.write(fos);
        }
        workbook.close();
    }
}

3. 多級聯(lián)動下拉列表

public void createCascadingDropdown() {
    Workbook workbook = new XSSFWorkbook();
    Sheet sheet = workbook.createSheet("多級聯(lián)動");
    
    // 第一級:省份
    String[] provinces = {"浙江省", "江蘇省", "廣東省"};
    DataValidationHelper helper = sheet.getDataValidationHelper();
    DataValidationConstraint provinceConstraint = 
        helper.createExplicitListConstraint(provinces);
    
    // 第二級:城市(使用名稱定義)
    Name cityName = workbook.createName();
    cityName.setNameName("cityData");
    cityName.setRefersToFormula("INDIRECT($A$2)"); // 根據(jù)A2單元格的值動態(tài)引用
    
    // 定義命名區(qū)域
    String[] zhejiangCities = {"杭州", "寧波", "溫州"};
    String[] jiangsuCities = {"南京", "蘇州", "無錫"};
    String[] guangdongCities = {"廣州", "深圳", "東莞"};
    
    // 在隱藏工作表存儲城市數(shù)據(jù)
    Sheet hiddenSheet = workbook.createSheet("hiddenData");
    for (int i = 0; i < provinces.length; i++) {
        String[] cities = null;
        if (i == 0) cities = zhejiangCities;
        else if (i == 1) cities = jiangsuCities;
        else cities = guangdongCities;
        
        Row row = hiddenSheet.createRow(i);
        for (int j = 0; j < cities.length; j++) {
            row.createCell(j).setCellValue(cities[j]);
        }
    }
    
    // 創(chuàng)建數(shù)據(jù)驗證
    DataValidationConstraint cityConstraint = 
        helper.createFormulaListConstraint("cityData");
    CellRangeAddressList cityRange = new CellRangeAddressList(1, 1, 1, 1);
    DataValidation cityValidation = helper.createValidation(cityConstraint, cityRange);
    sheet.addValidationData(cityValidation);
}

4. 從數(shù)據(jù)庫動態(tài)加載選項

@Service
public class DynamicDropdownService {
    
    @Autowired
    private DepartmentRepository departmentRepo;
    
    public void createDynamicDropdown(Workbook workbook, Sheet sheet) {
        // 從數(shù)據(jù)庫獲取部門列表
        List<Department> departments = departmentRepo.findAll();
        String[] deptNames = departments.stream()
            .map(Department::getName)
            .toArray(String[]::new);
        
        // 創(chuàng)建下拉驗證
        DataValidationHelper helper = sheet.getDataValidationHelper();
        DataValidationConstraint constraint = 
            helper.createExplicitListConstraint(deptNames);
        
        CellRangeAddressList addressList = 
            new CellRangeAddressList(1, 1000, 2, 2); // C列
        
        DataValidation validation = helper.createValidation(constraint, addressList);
        validation.setSuppressDropDownArrow(true); // 隱藏下拉箭頭
        sheet.addValidationData(validation);
    }
}

高級配置

1. 輸入提示和錯誤信息

// 設(shè)置輸入提示
validation.createPromptBox("部門選擇", "請從列表中選擇所屬部門");
validation.setShowPromptBox(true);

// 設(shè)置錯誤提示
validation.createErrorBox("無效輸入", "輸入值不在可選范圍內(nèi)");
validation.setErrorStyle(DataValidation.ErrorStyle.WARNING);

2. 限制輸入長度

// 創(chuàng)建文本長度約束
DataValidationConstraint lengthConstraint = 
    helper.createTextLengthConstraint(
        DataValidationConstraint.OperatorType.BETWEEN, 
        "1", "50"
    );

CellRangeAddressList range = new CellRangeAddressList(1, 100, 3, 3);
DataValidation validation = helper.createValidation(lengthConstraint, range);

性能優(yōu)化建議

批量設(shè)置驗證范圍

// 避免為每個單元格單獨創(chuàng)建驗證
CellRangeAddressList largeRange = 
    new CellRangeAddressList(1, 10000, 0, 0);

使用緩存機制

// 緩存常用下拉選項
private static final Map<String, String[]> DROPDOWN_CACHE = 
    new ConcurrentHashMap<>();

public String[] getCachedOptions(String type) {
    return DROPDOWN_CACHE.computeIfAbsent(type, k -> 
        loadOptionsFromDB(k)
    );
}

常見問題處理

下拉選項過多

// 當選項超過255個字符時,使用隱藏工作表存儲
Sheet hidden = workbook.createSheet("options");
Row row = hidden.createRow(0);
for (int i = 0; i < options.length; i++) {
    row.createCell(i).setCellValue(options[i]);
}

// 使用名稱引用
Name namedRange = workbook.createName();
namedRange.setNameName("largeOptions");
namedRange.setRefersToFormula("options!$A$1:$Z$100");

兼容性處理

// 處理不同Excel版本
if (workbook instanceof XSSFWorkbook) {
    // .xlsx文件支持更多選項
    validation.setShowErrorBox(true);
} else if (workbook instanceof HSSFWorkbook) {
    // .xls文件選項有限制
    validation.setErrorStyle(DataValidation.ErrorStyle.STOP);
}

完整工具類示例

public class ExcelDropdownUtil {
    
    public static void addDropdown(Sheet sheet, int firstRow, int lastRow, 
                                  int firstCol, int lastCol, String[] options) {
        
        DataValidationHelper helper = sheet.getDataValidationHelper();
        DataValidationConstraint constraint = 
            helper.createExplicitListConstraint(options);
        
        CellRangeAddressList addressList = 
            new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol);
        
        DataValidation validation = helper.createValidation(constraint, addressList);
        
        // 默認配置
        validation.setEmptyCellAllowed(true);
        validation.setShowPromptBox(true);
        validation.createPromptBox("提示", "請從下拉列表中選擇");
        
        sheet.addValidationData(validation);
    }
}

總結(jié)

通過Apache POI的數(shù)據(jù)驗證功能,我們可以輕松實現(xiàn)Excel下拉框的創(chuàng)建。關(guān)鍵點包括:

  • 使用DataValidationHelper創(chuàng)建約束
  • 正確設(shè)置驗證范圍
  • 合理處理多級聯(lián)動
  • 注意性能和兼容性問題

掌握這些技巧后,就能創(chuàng)建出功能豐富、用戶友好的Excel數(shù)據(jù)錄入模板。

一般工作中需要后端下載時,多數(shù)用于從數(shù)據(jù)庫動態(tài)加載選項

/**
     * 模板下載
     */
    @Override
    public void exportExcel(HttpServletResponse response) throws ApiException {
        List<CsiServer> csiServerList = csiServerMapper.getAllServer();
        List<String> serverList = csiServerList.stream()
                .map(CsiServer::getServerAllname)
                .filter(Objects::nonNull) // 防止 null 值
                .collect(Collectors.toList());

        if (serverList.isEmpty()) {
            serverList.add(" "); // Excel 下拉不能完全空,至少一個占位
        }

        String[] serverArray = serverList.toArray(new String[0]);

//        String debugJoined = String.join(",", serverArray);
//        log.info("下拉選項總長度: {}, 內(nèi)容預(yù)覽: {}", debugJoined.length(),
//                debugJoined.length() > 100 ? debugJoined.substring(0, 100) + "..." : debugJoined);
//
//        if (debugJoined.length() > 255) {
//            log.warn("?? 下拉選項超長({} > 255),Excel將無法顯示下拉框!", debugJoined.length());
//            // 臨時截斷測試
//            // serverArray = new String[]{"選項過多,請聯(lián)系管理員"};
//        }

        Workbook workbook = null;
        InputStream templateStream = null;

        try {
            // 1. 從 classpath 加載模板
            ClassPathResource classPathResource = new ClassPathResource(ORDERGRAIN_INBOUND_TEMPLATE);
            templateStream = classPathResource.getInputStream();

            // 2. 根據(jù)模板創(chuàng)建 Workbook(支持 .xlsx)
            workbook = new XSSFWorkbook(templateStream);

            // 3. 獲取要添加下拉框的工作表(假設(shè)是第一個 sheet,或按名稱獲取)
            Sheet sheet = workbook.getSheetAt(0); // 或 workbook.getSheet("SheetName");

            // 4. 創(chuàng)建下拉框(例如:A列第2行到第1000行)
            DataValidation dataValidation = PoiUtil.getDataValidation(sheet, serverArray, 23, 1, 999);

            // 5. 添加驗證規(guī)則
            sheet.addValidationData(dataValidation);

            // 6. 設(shè)置響應(yīng)頭,用于瀏覽器下載
            String fileName = URLEncoder.encode("收貨數(shù)據(jù)導(dǎo)入模板.xlsx", StandardCharsets.UTF_8.toString());
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            // 3. 設(shè)置字符編碼(避免文件名中文亂碼)
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());

            // 7. 寫入響應(yīng)輸出流
            workbook.write(response.getOutputStream());
            response.getOutputStream().flush();

        } catch (IOException e) {
            throw new ApiException(ResultCode.FAULT,"導(dǎo)出Excel失敗");
        } finally {
            try {
                if (workbook != null) {
                    workbook.close();
                }
                if (templateStream != null) {
                    templateStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddressList;

@Slf4j
public class PoiUtil {

    /**
     * Excel 下拉框數(shù)據(jù)驗證工具方法
     * 功能:為指定工作表的目標列、行范圍創(chuàng)建「靜態(tài)下拉框」(基于顯式選項數(shù)組),并配置錯誤提示機制
     * 適用場景:下拉選項少(總字符數(shù)≤255,Excel原生限制)、選項固定的場景
     *
     * @param sheet           目標工作表(如XSSFSheet、HSSFSheet),必須已創(chuàng)建且非空
     * @param dropDownOptions 下拉框選項數(shù)組,元素為字符串類型;不可為null(空選項需傳空數(shù)組),元素不可含逗號(Excel下拉框默認用逗號分隔選項)
     * @param column          下拉框所在列的索引(POI中列索引從0開始,例:0=A列、1=B列、2=C列...)
     * @param firstRow        下拉框生效的起始行索引(POI中行索引從0開始,例:0=Excel第1行、1=Excel第2行...),需≥0
     * @param lastRow         下拉框生效的結(jié)束行索引(需≥firstRow,例:99=Excel第100行),控制下拉框覆蓋的行數(shù)范圍
     * @return DataValidation 配置完成的數(shù)據(jù)驗證對象(包含下拉框規(guī)則),需通過 {@link Sheet#addValidationData(DataValidation)} 方法添加到工作表才會生效
     * @note 1. 字符限制:選項數(shù)組總字符數(shù)(含默認分隔符逗號)不可超過255,否則Excel會報錯,需改用「動態(tài)下拉框」(隱藏工作表+公式引用);
     * 2. 選項規(guī)范:數(shù)組元素不可包含逗號(,),否則會被Excel解析為多個選項,若需含逗號需自定義分隔符(需配合其他API);
     * 3. 生效方式:返回的DataValidation對象需手動添加到工作表,未添加則下拉框不顯示;
     * 4. 錯誤提示:默認啟用錯誤提示框(輸入非下拉選項時觸發(fā)),可通過返回對象的setXXX方法調(diào)整提示文案、樣式;
     * 5. 版本兼容:支持Excel 2003(.xls,HSSFWorkbook)和2007+(.xlsx,XSSFWorkbook),無需修改方法邏輯
     */
    public static DataValidation getDataValidation(Sheet sheet,
                                                   String[] dropDownOptions,
                                                   int column,
                                                   int firstRow,
                                                   int lastRow) {
        // 1. 定義下拉框生效的單元格范圍:[firstRow, lastRow] 行 × [column, column] 列(單個列的連續(xù)行)
        CellRangeAddressList addressList = new CellRangeAddressList(firstRow, lastRow, column, column);

        // 2. 獲取工作表的數(shù)據(jù)驗證助手,用于構(gòu)建驗證規(guī)則
        DataValidationHelper validationHelper = sheet.getDataValidationHelper();

        // 3. 創(chuàng)建顯式列表約束:下拉選項直接從傳入的數(shù)組中獲取,適用于選項固定的場景
        DataValidationConstraint constraint = validationHelper.createExplicitListConstraint(dropDownOptions);

        // 4. 綁定約束與單元格范圍,生成數(shù)據(jù)驗證對象(下拉框核心配置)
        DataValidation dataValidation = validationHelper.createValidation(constraint, addressList);

        // 5. 配置錯誤提示:輸入值不在下拉列表中時,顯示錯誤提示框
        dataValidation.setShowErrorBox(true);

        return dataValidation;
    }

}

效果圖

手動選擇下拉框中選項,也可以粘貼上去,如果不是下拉框中任何一個值就會報錯誤提示。

到此這篇關(guān)于Java使用Apache POI在Excel中創(chuàng)建下拉列表的文章就介紹到這了,更多相關(guān)Java Excel創(chuàng)建下拉列表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java?LinkedList實現(xiàn)班級信息管理系統(tǒng)

    Java?LinkedList實現(xiàn)班級信息管理系統(tǒng)

    這篇文章主要為大家詳細介紹了Java?LinkedList實現(xiàn)班級信息管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • 深入理解Java設(shè)計模式之簡單工廠模式

    深入理解Java設(shè)計模式之簡單工廠模式

    這篇文章主要介紹了JAVA設(shè)計模式之簡單工廠模式的的相關(guān)資料,文中示例代碼非常詳細,供大家參考和學(xué)習(xí),感興趣的朋友可以了解下
    2021-11-11
  • 如何基于java或js獲取URL返回狀態(tài)碼

    如何基于java或js獲取URL返回狀態(tài)碼

    這篇文章主要介紹了如何基于java或js獲取URL返回狀態(tài)碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11
  • Java枚舉_動力節(jié)點Java學(xué)院整理

    Java枚舉_動力節(jié)點Java學(xué)院整理

    enum 的全稱為 enumeration, 是 JDK 5 中引入的新特性,存放在 java.lang 包中。這篇文章給大家介紹Java枚舉相關(guān)知識,需要的的朋友參考下
    2017-04-04
  • Java將本地項目部署到Linux服務(wù)器的實踐

    Java將本地項目部署到Linux服務(wù)器的實踐

    本文主要介紹了Java將本地項目部署到Linux服務(wù)器的實踐,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧<BR>
    2022-06-06
  • Java中ModelMapper?的高級使用

    Java中ModelMapper?的高級使用

    本文主要介紹了Java中ModelMapper?的高級使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Java兩整數(shù)相除向上取整的方式詳解(Math.ceil())

    Java兩整數(shù)相除向上取整的方式詳解(Math.ceil())

    在調(diào)外部接口獲取列表數(shù)據(jù)時,需要判斷是否已經(jīng)取完了所有的值,因此需要用到向上取整,下面這篇文章主要給大家介紹了關(guān)于Java兩整數(shù)相除向上取整的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • Mybatis Log控制臺如何輸出打印SQL語句

    Mybatis Log控制臺如何輸出打印SQL語句

    這篇文章主要介紹了Mybatis Log控制臺如何輸出打印SQL語句,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • 使用cmd根據(jù)WSDL網(wǎng)址生成java客戶端代碼的實現(xiàn)

    使用cmd根據(jù)WSDL網(wǎng)址生成java客戶端代碼的實現(xiàn)

    這篇文章主要介紹了使用cmd根據(jù)WSDL網(wǎng)址生成java客戶端代碼的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • IDEA新建javaWeb以及Servlet簡單實現(xiàn)小結(jié)

    IDEA新建javaWeb以及Servlet簡單實現(xiàn)小結(jié)

    這篇文章主要介紹了IDEA新建javaWeb以及Servlet簡單實現(xiàn)小結(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11

最新評論

财经| 汕头市| 琼结县| 夏河县| 彭水| 宁德市| 美姑县| 武平县| 崇仁县| 佛山市| 桐庐县| 吕梁市| 务川| 惠水县| 武汉市| 吉林省| 垦利县| 宁夏| 上犹县| 怀仁县| 毕节市| 西安市| 麻江县| 东阳市| 临夏县| 罗定市| 蕉岭县| 长宁县| 绥阳县| 化州市| 灯塔市| 靖州| 庐江县| 宁德市| 蓝田县| 嘉兴市| 河西区| 澄江县| 宣化县| 余干县| 乐业县|