java读取dbf文件并和Excel文件数据对比,校验文件,输出新的dbf文件

@[TOC]

文章所用jar文件

用到的jar
建议使用,版本冲突已经解决

DBF文件操作工具类--DbfWriterAndReadUtil

package com.yuanzhan.dbf.util;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.linuxense.javadbf.DBFDataType;
import com.linuxense.javadbf.DBFField;
import com.linuxense.javadbf.DBFReader;
import com.linuxense.javadbf.DBFWriter;

public class DbfWriterAndReadUtil {

    /**
     * 创建dbf
     * 
     * @param path
     *            文件路径
     * @param fieldList
     *            字段
     * @param charsetName
     *            编码字符集
     * @throws IOException
     */
    public static void createDbf(String path,
            List<Map<String, String>> fieldList, String charsetName)
            throws IOException {
        // 创建dbf文件列对象--根据传入集合长度确定该数组长度
        DBFField[] fields = new DBFField[fieldList.size()];
        int index = 0;
        // 循环当前列数组,写入每行数据
        for (Map<String, String> fieldMap : fieldList) {
            // 创建dbf文件行数据对象
            DBFField field = new DBFField();
            // 获取键值--即表头
            field.setName(fieldMap.get("name"));// 字段名称
            // 设置该列数据类型
            field.setType(DBFDataType.CHARACTER);// 指定字段类型为字符串
            // 指定该列数据长度
            field.setLength(Integer.valueOf(fieldMap.get("length")));// 指定长度
            // 写入到列数组中
            fields[index] = field;
            index++;
        }
        // 定义DBFWriter实例用来写DBF文件
        DBFWriter dbfWriter = new DBFWriter(new FileOutputStream(path),
                Charset.forName(charsetName));
        // 设置字段
        dbfWriter.setFields(fields);
        // 写入dbf文件并关闭
        dbfWriter.close();
    }

    /**
     * 获取字段名--表头名
     * 
     * @param path
     *            文件路径
     * @param charsetName
     *            编码类型
     * @return
     * @throws IOException
     */
    public static String[] getFieldName(String path, String charsetName)
            throws IOException {
        // 读取文件数据对象
        DBFReader dbfReader = new DBFReader(new FileInputStream(path),
                Charset.forName(charsetName));
        int fieldCount = dbfReader.getFieldCount();// 获取字段数量
        // 创建数组
        String[] fieldName = new String[fieldCount];
        // 循环写入数据值
        for (int i = 0; i < fieldCount; i++) {
            // 获取表头名--写入数组
            fieldName[i] = dbfReader.getField(i).getName();
        }
        // 关闭资源
        dbfReader.close();
        return fieldName;
    }

    /**
     * 写dbf文件
     * 
     * @param dbfName
     *            文件名
     * @param strutName
     *            列名集合
     * @param strutType
     *            单元格数据类型集合
     * @param strutLength
     *            单元格数据长度
     * @param data
     *            传入的行数据--双重数组
     */
    public static void generateDbfFromArray(String dbfName, String[] strutName,
            byte[] strutType, int[] strutLength, Object[][] data) {
        // io输出流
        OutputStream fos = null;
        try {
            //列名数组长度--即列数
            int fieldCount = strutName.length;
            //创建单行数据
            DBFField[] fields = new DBFField[fieldCount];
            //设置单行数据单个数据列名,数据类型,数据长度
            for (int i = 0; i < fieldCount; i++) {
                //实例化单行数据
                fields[i] = new DBFField();
                //列名
                fields[i].setName(strutName[i]);
                //数据类型
                fields[i].setDataType(strutType[i]);
                //数据长度
                fields[i].setFieldLength(strutLength[i]);
            }
            //写入流对象
            DBFWriter writer = new DBFWriter();
            //写入
            writer.setFields(fields);
            //循环单行写入
            for (int i = 0; i < fieldCount - 1; i++) {
                writer.addRecord(data[i]);
            }
            //输出流实例
            fos = new FileOutputStream(dbfName);
            //输出文件
            writer.write(fos);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                fos.close();
            } catch (Exception e) {
            }
        }

    }

    /**
     * 读dbf文件
     * @param path 文件路径
     * @param charsetName 编码
     * @return
     * @throws IOException
     */
    public static List<Map<String, String>> readDbf(String path,
            String charsetName) throws IOException {
        //存储读取到类容的集合
        List<Map<String, String>> rowList = new ArrayList<Map<String, String>>();
        //创建文件输入流
        DBFReader dbfReader = new DBFReader(new FileInputStream(path),
                Charset.forName(charsetName));
        //声明单行数据数组
        Object[] rowValues;
        //循环读取
        while ((rowValues = dbfReader.nextRecord()) != null) {
            //键值方式存储单行数据
            Map<String, String> rowMap = new HashMap<String, String>();
            //循环写入当行数据到map集合
            for (int i = 0; i < rowValues.length; i++) {
                //key 列名 value 当前单元格值
                rowMap.put(dbfReader.getField(i).getName(),
                        String.valueOf(rowValues[i]).trim());
            }
            //写入集合
            rowList.add(rowMap);
        }
        //关闭输入流
        dbfReader.close();
        return rowList;
    }
}

Excel文件操作工具类--

package com.yuanzhan.dbf.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelWriterAndReadUtil {

    /**
     * 读取excel文件--返回dbf文件格式
     * @param fileName 读取的文件路径
     * @return
     * @throws Exception
     */
    public static List<Map<String,String>> readExcel(String fileName) throws Exception {
        //打开需要读取的文件
        FileInputStream inputStream = new FileInputStream(new File(fileName));
        //读取工作簿
        XSSFWorkbook wordBook = new XSSFWorkbook(inputStream);
        //读取工作表,从0开始
        XSSFSheet sheet = wordBook.getSheetAt(0);
        //存储数据集合
        List<Map<String,String>> mapList=new ArrayList<Map<String,String>>();
        //存储表头数据
        Map<Integer,String > stringMap=new HashMap<Integer, String>();
        int lastRowNum = sheet.getLastRowNum(); //获取表格内容的最后一行的行数
        //循环按行读取数据
        for(int i=0;i<=lastRowNum;i++){
            //单个数据集合--保持和dbf文件格式相同--方便对比
            Map<String,String> map=new HashMap<String,String>();
             //读取第i行
            XSSFRow row = sheet.getRow(i);
            int columnNum = row.getLastCellNum();//获取每一行的最后一列的列号,即总列数
            //循环读取单行数据
            for(int j=0;j<columnNum;j++){
                //读取j单元格
                XSSFCell cell = row.getCell(j);//获取单元格对象
                //设置cell数据类型
                cell.setCellType(CellType.STRING);
                //获取值
                String value = cell.getStringCellValue();
                //第一行是存储表头数据
                if (i==0){
                    //单元格值
                    stringMap.put(j,value);
                }else{
                    //否则存储表头--值数据
                    map.put(stringMap.get(j),value);
                }
            }
            if (i!=0){
                //存入集合
                mapList.add(map);
            }
        }
        //关闭输入流
        inputStream.close();
        //关闭工作簿
        wordBook.close();
        return mapList;
    }
    
    /**
     * 写入工作簿文件
     * @throws Exception
     */
    public void writeExcel() throws Exception {
        //创建工作簿
        XSSFWorkbook workbook = new XSSFWorkbook();
        //创建工作表
        XSSFSheet sheet = workbook.createSheet();
        //创建行
        XSSFRow row = sheet.createRow(2);
        //创建单元格,操作第三行第三列
        XSSFCell cell = row.createCell(2,CellType.STRING);
        cell.setCellValue("hellword");
        //路径
        FileOutputStream outputStream = new FileOutputStream(new File("D:/bb.xlsx"));
        workbook.write(outputStream);
        //关闭工作簿
        workbook.close();
    }
}

调用工具类示例

/**
 * 项目名:DbfExcelDemo
 * 日  期:2019/11/11
 * 包  名:com.yuanzhan.dbf.main
 *
 * @author: liujia
 */
package com.yuanzhan.dbf.main;
import com.linuxense.javadbf.DBFField;
import com.yuanzhan.dbf.util.DbfWriterAndReadUtil;
import com.yuanzhan.dbf.util.ExcelWriterAndReadUtil;
import java.util.List;
import java.util.Map;
/**
 * 对比,实例调用
 * @author admin
 *
 */
public class DemoMain {

    public static Object FileConversion(String dbfFile, String excelFile,
            String dowFile) {
        List<Map<String, String>> mapList = null;
        try {
            // 读取Excel文件
            mapList = ExcelWriterAndReadUtil.readExcel(excelFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 读取dbf文件
        // 获取文件内容集合
        List<Map<String, String>> getRowList = null;
        // 写入的列名数组
        String[] strutName = null;
        // 单元格数据类型,与上面列名一一对应
        byte[] strutType = null;
        // 单元格数据长度
        int[] strutLength = null;
        // 获取dbf文件的列名集合
        String[] fieldName = new String[] {};
        try {
            // 获取dbf文件的列名集合
            fieldName = DbfWriterAndReadUtil.getFieldName(dbfFile, "GBK");
            // 实例化数组
            strutName = new String[fieldName.length];
            // 实例化数组
            strutType = new byte[fieldName.length];
            //实例化数组
            strutLength = new int[fieldName.length];
            //设置数据列名,数据类型,数据长度
            for (int i = 0; i < fieldName.length; i++) {
                strutName[i] = fieldName[i];
                strutType[i] = DBFField.FIELD_TYPE_C;
                strutLength[i] = 50;
            }
            // 获取文件内容集合
            getRowList = DbfWriterAndReadUtil.readDbf(dbfFile, "GBK");
            // 多行数据集合
            Object[][] data = new Object[getRowList.size()][];
            int count = 0;
            // 对比,,dbf文件数据
            for (Map<String, String> map1 : getRowList) {
                // 单行数据集合
                String[] text = new String[fieldName.length];
                //根据列名获取两边文件的单元格数据
                //excel数据
                for (Map<String, String> map2 : mapList) {
                    //根据name和address检索数据
                    if (map1.get("name").equals(map2.get("name"))
                            && map1.get("address").equals(map2.get("address"))) {
                        //对比cardId数据
                        if (map1.get("cardId").equals(map2.get("cardId"))) {
                            //true,返还dbf原数据
                            for (int i = 0; i < strutName.length; i++) {
                                text[i] = map1.get(strutName[i]);
                            }
                            //结束循环
                            continue;
                        } else {
                            //false,返回Excel数据
                            for (int i = 0; i < strutName.length; i++) {
                                //获取表头--对比
                                if (strutName[i].equals("cardId")) {
                                    text[i] = map2.get(strutName[i]);
                                } else {
                                    text[i] = map1.get(strutName[i]);
                                }
                            }
                            continue;
                        }
                    }
                }
                //存储单行数据
                data[count] = text;
                count++;
            }
            // 写入新的dbf文件
            DbfWriterAndReadUtil.generateDbfFromArray(dowFile, strutName,
                    strutType, strutLength, data);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}
本Demo开发环境jdk1.7,开发工具:MyEclipse Professional 2014
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354