You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Apache POI的Java GUI产品编码生成功能实现咨询

解决方案与代码优化

以下是针对你的需求调整后的代码,解决了编码拼接、资源泄漏、输入验证等问题,确保能正确从Excel中读取对应数据并生成符合格式的产品编码:

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;

public class ProductCodeGenerator extends JFrame implements ActionListener {
    private JLabel brandLabel, typeLabel, deliveryLabel, packageLabel, nameLabel, codeLabel;
    private JTextField brandField, typeField, deliveryField, packageField, nameField;
    private JButton generateButton;

    public ProductCodeGenerator() {
        // 创建GUI组件
        brandLabel = new JLabel("品牌:");
        typeLabel = new JLabel("类型:");
        deliveryLabel = new JLabel("配送方式:");
        packageLabel = new JLabel("包装:");
        nameLabel = new JLabel("名称:");
        codeLabel = new JLabel("产品编码:");
        brandField = new JTextField(10);
        typeField = new JTextField(10);
        deliveryField = new JTextField(10);
        packageField = new JTextField(10);
        nameField = new JTextField(10);
        generateButton = new JButton("生成编码");
        generateButton.addActionListener(this);

        // 添加组件到面板
        JPanel panel = new JPanel(new GridLayout(6, 2));
        panel.add(brandLabel);
        panel.add(brandField);
        panel.add(typeLabel);
        panel.add(typeField);
        panel.add(deliveryLabel);
        panel.add(deliveryField);
        panel.add(packageLabel);
        panel.add(packageField);
        panel.add(nameLabel);
        panel.add(nameField);
        panel.add(generateButton);
        panel.add(codeLabel);
        add(panel);

        // 设置窗口属性
        setTitle("产品编码生成器");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400, 200);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
        // 输入验证
        if (brandField.getText().isEmpty() || typeField.getText().isEmpty() ||
            deliveryField.getText().isEmpty() || packageField.getText().isEmpty() ||
            nameField.getText().isEmpty()) {
            JOptionPane.showMessageDialog(this, "请填写所有输入项", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        try {
            // 读取用户输入
            String brand = brandField.getText().trim();
            String type = typeField.getText().trim();
            String delivery = deliveryField.getText().trim();
            String packageName = packageField.getText().trim();
            String name = nameField.getText().trim();

            // 读取Excel文件(使用try-with-resources自动关闭资源)
            try (FileInputStream file = new FileInputStream(new File("DITCO PRODUCT CODE.xlsx"));
                 Workbook workbook = new XSSFWorkbook(file)) {
                Sheet sheet = workbook.getSheetAt(0);

                // 获取对应数据的行索引
                int brandRowIndex = getRowIndexByColumnValue(sheet, "Marka", brand);
                int typeRowIndex = getRowIndexByColumnValue(sheet, "Tip", type);
                int deliveryRowIndex = getRowIndexByColumnValue(sheet, "Gönderim Tipi", delivery);
                int groupRowIndex = getRowIndexByColumnValue(sheet, "1-40 Bottle", packageName);

                // 检查索引是否有效
                if (brandRowIndex == -1 || typeRowIndex == -1 || deliveryRowIndex == -1 || groupRowIndex == -1) {
                    JOptionPane.showMessageDialog(this, "Excel中未找到匹配的输入项", "错误", JOptionPane.ERROR_MESSAGE);
                    return;
                }

                // 提取产品序号(假设名称格式为P3、G8等,取数字部分)
                int productIndex;
                try {
                    productIndex = Integer.parseInt(name.replaceAll("[^0-9]", ""));
                } catch (NumberFormatException ex) {
                    JOptionPane.showMessageDialog(this, "名称格式错误,请输入包含数字的名称", "错误", JOptionPane.ERROR_MESSAGE);
                    return;
                }

                // 从Excel读取各部分编码
                int brandCode = (int) sheet.getRow(brandRowIndex).getCell(0).getNumericCellValue();
                int typeCode = (int) sheet.getRow(typeRowIndex).getCell(1).getNumericCellValue();
                int deliveryCode = (int) sheet.getRow(deliveryRowIndex).getCell(2).getNumericCellValue();
                // 计算组与产品的组合编码(组号*10 + 产品序号)
                int groupProductCode = groupRowIndex * 10 + productIndex;

                // 拼接成目标编码(确保配送码为两位,不足补零)
                String productCode = String.format("%d%d%02d%d", brandCode, typeCode, deliveryCode, groupProductCode);

                // 显示编码
                codeLabel.setText("产品编码: " + productCode);
            }
        } catch (FileNotFoundException ex) {
            JOptionPane.showMessageDialog(this, "未找到Excel文件", "错误", JOptionPane.ERROR_MESSAGE);
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(this, "生成编码失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            ex.printStackTrace();
        }
    }

    /**
     * 根据列名和单元格值,返回对应的行索引(从1开始)
     */
    private int getRowIndexByColumnValue(Sheet sheet, String columnName, String value) {
        // 先找到目标列的索引
        int columnIndex = -1;
        Row headerRow = sheet.getRow(0);
        if (headerRow == null) {
            return -1;
        }
        for (int i = 0; i < headerRow.getLastCellNum(); i++) {
            Cell cell = headerRow.getCell(i);
            if (cell != null && cell.getCellType() == CellType.STRING && cell.getStringCellValue().equals(columnName)) {
                columnIndex = i;
                break;
            }
        }
        if (columnIndex == -1) {
            return -1;
        }

        // 在目标列中查找匹配值的行
        for (int i = 1; i <= sheet.getLastRowNum(); i++) {
            Row row = sheet.getRow(i);
            if (row == null) {
                continue;
            }
            Cell cell = row.getCell(columnIndex);
            if (cell != null) {
                String cellValue;
                if (cell.getCellType() == CellType.STRING) {
                    cellValue = cell.getStringCellValue().trim();
                } else if (cell.getCellType() == CellType.NUMERIC) {
                    cellValue = String.valueOf((int) cell.getNumericCellValue());
                } else {
                    continue;
                }
                if (cellValue.equals(value)) {
                    return i;
                }
            }
        }
        return -1;
    }

    public static void main(String[] args) {
        // 在EDT中启动GUI
        SwingUtilities.invokeLater(ProductCodeGenerator::new);
    }
}

关键修改说明

  • 编码拼接方式优化:使用String.format进行字符串拼接,通过%02d确保配送方式编码始终为两位(比如配送码是3时,自动补零为03),完全匹配你需要的编码格式(如示例中的251183)。
  • 资源自动管理:使用try-with-resources语句自动关闭FileInputStream和Workbook,避免资源泄漏。
  • 输入验证增强:增加空输入检查、名称格式验证,以及Excel索引有效性检查,通过弹窗提示用户错误,提升用户体验。
  • 方法命名优化:将getIndex重命名为getRowIndexByColumnValue,更清晰表达方法功能;同时优化了单元格值的读取逻辑,支持数值型和字符串型的单元格值匹配。
  • GUI线程安全:使用SwingUtilities.invokeLater启动GUI,符合Swing线程安全规范。

注意事项

  1. 确保Excel文件路径正确,若文件不在程序运行目录下,需使用绝对路径。
  2. Excel的结构需与代码逻辑匹配:
    • 第一行为列名(如"Marka"对应品牌名称列);
    • 品牌编码在品牌名称所在行的第0列;
    • 类型编码在类型名称所在行的第1列;
    • 配送方式编码在配送名称所在行的第2列;
    • 包装对应的组号在包装名称所在行的对应列(代码中为"1-40 Bottle"列)。

内容的提问来源于stack exchange,提问作者AhmetArslan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 23:47:02