Java生成DBF文件的工具类

Java生成DBF文件的工具类

import com.linuxense.javadbf.DBF;
import com.linuxense.javadbf.DBFField;
import com.linuxense.javadbf.DBFRecord;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;

public class DBFGenerator {

    /**
     * 创建 DBF 文件
     * @param filePath 目标文件路径
     * @param fields 字段名和字段类型的映射
     * @param data 数据列表,包含多行记录
     * @param dateFormat 自定义日期格式
     * @param nullValue 自定义空值表示方式
     * @throws IOException
     */
    public static void createDBFFile(String filePath, Map<String, String> fields, List<Map<String, Object>> data, 
                                     String dateFormat, String nullValue) throws IOException {
        // 字段重复检查
        checkDuplicateFields(fields);

        // 创建 DBF 文件
        DBF dbf = new DBF();

        // 根据字段信息动态添加字段
        for (Map.Entry<String, String> field : fields.entrySet()) {
            DBFField dbfField = new DBFField();
            dbfField.setName(field.getKey());

            // 根据字段类型设置字段类型
            switch (field.getValue().toUpperCase()) {
                case "C":
                    dbfField.setType(DBFField.FIELD_TYPE_C);  // 字符串类型
                    dbfField.setLength(50);  // 可以设置字段长度
                    break;
                case "N":
                    dbfField.setType(DBFField.FIELD_TYPE_N);  // 数字类型
                    dbfField.setLength(20);  // 可以设置字段长度
                    break;
                case "D":
                    dbfField.setType(DBFField.FIELD_TYPE_D);  // 日期类型
                    break;
                case "L":
                    dbfField.setType(DBFField.FIELD_TYPE_L);  // 逻辑类型(布尔值)
                    break;
                case "F":
                    dbfField.setType(DBFField.FIELD_TYPE_F);  // 浮动数字类型
                    dbfField.setLength(20);  // 设置长度
                    break;
                default:
                    throw new IllegalArgumentException("不支持的字段类型: " + field.getValue());
            }
            dbf.addField(dbfField);
        }

        // 根据传入的数据列表创建记录
        for (Map<String, Object> row : data) {
            DBFRecord record = new DBFRecord(dbf);

            // 设置记录中的字段值
            int index = 0;
            for (String fieldName : fields.keySet()) {
                Object value = row.get(fieldName);
                if (value == null) {
                    value = nullValue;  // 如果为空值,替换为 nullValue
                }
                setFieldValue(record, index, value, fields.get(fieldName), dateFormat);
                index++;
            }

            // 将记录添加到 DBF 文件
            dbf.addRecord(record);
        }

        // 将 DBF 文件写入到指定的路径
        dbf.write(new File(filePath));

        System.out.println("DBF 文件创建成功: " + filePath);
    }

    /**
     * 字段值赋值
     * @param record DBF 记录
     * @param index 字段索引
     * @param value 字段值
     * @param fieldType 字段类型
     * @param dateFormat 自定义日期格式
     */
    private static void setFieldValue(DBFRecord record, int index, Object value, String fieldType, String dateFormat) {
        try {
            if (value instanceof String) {
                record.setString(index, (String) value);
            } else if (value instanceof Integer) {
                record.setInt(index, (Integer) value);
            } else if (value instanceof Double) {
                record.setDouble(index, (Double) value);
            } else if (value instanceof Boolean) {
                record.setBoolean(index, (Boolean) value);
            } else if (value instanceof java.util.Date && "D".equalsIgnoreCase(fieldType)) {
                // 处理日期类型
                SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
                record.setDate(index, sdf.format((java.util.Date) value));
            } else {
                // 对其他数据类型,抛出异常
                throw new IllegalArgumentException("不支持的字段值类型: " + value.getClass());
            }
        } catch (Exception e) {
            throw new RuntimeException("字段值设置失败: " + e.getMessage(), e);
        }
    }

    /**
     * 检查字段名是否重复
     * @param fields 字段名和类型映射
     */
    private static void checkDuplicateFields(Map<String, String> fields) {
        if (fields.size() != fields.keySet().size()) {
            throw new IllegalArgumentException("字段名不能重复");
        }
    }

    public static void main(String[] args) {
        try {
            // 示例字段:字段名 -> 字段类型
            Map<String, String> fields = Map.of(
                "NAME", "C",
                "AGE", "N",
                "BIRTHDAY", "D",
                "IS_ACTIVE", "L",
                "SALARY", "F"
            );

            // 示例数据:每行是一个 Map,键为字段名,值为对应的字段值
            List<Map<String, Object>> data = List.of(
                Map.of("NAME", "Alice", "AGE", 30, "BIRTHDAY", new java.util.Date(), "IS_ACTIVE", true, "SALARY", 5000.75),
                Map.of("NAME", "Bob", "AGE", 25, "BIRTHDAY", new java.util.Date(), "IS_ACTIVE", false, "SALARY", 4500.50)
            );

            // 自定义日期格式和空值表示方式
            createDBFFile("output.dbf", fields, data, "yyyy-MM-dd", "NULL");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

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

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;

public class ExcelReader {

    /**
     * 读取 Excel 文件并返回 List<Map<String, Object>> 格式的数据
     * @param filePath Excel 文件路径
     * @return List<Map<String, Object>> 格式的学号、姓名数据
     * @throws IOException
     */
    public static List<Map<String, Object>> readExcel(String filePath) throws IOException {
        List<Map<String, Object>> resultList = new ArrayList<>();
        FileInputStream fis = new FileInputStream(new File(filePath));
        Workbook workbook = new XSSFWorkbook(fis);  // 读取 Excel 文件

        // 获取第一个工作表
        Sheet sheet = workbook.getSheetAt(0);
        
        // 遍历行
        for (int rowIndex = 1; rowIndex <= sheet.getPhysicalNumberOfRows(); rowIndex++) {  // 从第2行开始,跳过表头
            Row row = sheet.getRow(rowIndex);
            if (row != null) {
                Map<String, Object> map = new HashMap<>();

                // 每两列为一组,学号在偶数列,姓名在奇数列
                for (int colIndex = 0; colIndex < row.getPhysicalNumberOfCells(); colIndex += 2) {
                    // 学号
                    Cell studentIdCell = row.getCell(colIndex);
                    // 姓名
                    Cell nameCell = row.getCell(colIndex + 1);

                    // 获取学号和姓名的值
                    if (studentIdCell != null && nameCell != null) {
                        map.put("学号", studentIdCell.getStringCellValue());
                        map.put("姓名", nameCell.getStringCellValue());
                    }
                }

                // 将每行数据加入到结果列表
                resultList.add(map);
            }
        }

        // 关闭工作簿
        workbook.close();
        fis.close();

        return resultList;
    }

    public static void main(String[] args) {
        try {
            List<Map<String, Object>> result = readExcel("students.xlsx"); // 请替换成你的文件路径
            for (Map<String, Object> map : result) {
                System.out.println(map);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值