DBF文件格式是一種比較“古老”的數據庫文件格式了。要不是最近項目中需要,筆者恐怕到今天也不曾聽說過DBF文件格式。
作用:DBF數據庫格式是DOS系統中的dBase數據庫和FoxPro數據庫所使用的數據庫格式。如今,如果電腦上沒有安裝這兩款軟件,可以使用Excel打開。
package zj.jdbc.util; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import com.linuxense.javadbf.DBFDataType; import com.linuxense.javadbf.DBFField; import com.linuxense.javadbf.DBFReader; import com.linuxense.javadbf.DBFWriter; import zj.check.util.CheckUtil; import zj.common.exception.ServiceException; import zj.io.util.FileUtil; import zj.java.util.JavaUtil; import zj.jdbc.bean.DBFRead; import zj.jdbc.bean.DBFWrite; import zj.reflect.util.TypeUtil; /** * 類名 :DBFUtil<br> * * @version 1.00 (2014.09.15) * @author SHNKCS 張軍 {@link <a target=_blank href="http://m.eyofj.com">上海加盾信息科技有限公司</a> <a target=_blank href="http://m.eyofj.com">張軍個人網站</a> <a target=_blank href="http://user.qzone.qq.com/360901061/">張軍QQ空間</a>} */ public class DBFUtil implements Serializable { private static final long serialVersionUID = 1L; private static final Logger logger = Logger.getLogger(DBFUtil.class); // str = Md5Util.toMd5("zhangjundbf201611040930"); // System.out.println(str); // str = Md5Util.toMd5("zhangjundbf201611040931"); // System.out.println(str); /** * 讀取DBF數據 * * @param path * dbf文件路徑 * @author 張軍 * @date 2015-11-03 21:59:00 * @modifiyNote * @version 1.0 * @return */ public static void readDBF(DBFRead p_read) { // 清空值 p_read.reset(); InputStream fis = null; try { // 讀取文件的輸入流 fis = new FileInputStream(p_read.paramPath); // 根據輸入流初始化一個DBFReader實例,用來讀取DBF文件信息 p_read.rtnReader = new DBFReader(fis, p_read.paramCharset); // 調用DBFReader對實例方法得到path文件行數,包含刪除和隱藏的行 p_read.rtnRecordsCount = p_read.rtnReader.getRecordCount(); // 調用DBFReader對實例方法得到path文件中字段的個數 p_read.rtnFieldsCount = p_read.rtnReader.getFieldCount(); // 取出字段信息 for (int i = 0; i < p_read.rtnFieldsCount; i++) { // 獲取DBF字段信息 DBFField field = p_read.rtnReader.getField(i); p_read.rtnFields.add(field); // 轉換為大寫 String fieldName = JavaUtil.toUpperCase(JavaUtil.trim(field.getName())); p_read.rtnFieldNames.add(fieldName); } Object[] rowValue = null; // 一條條取出path文件中記錄 while ((rowValue = p_read.rtnReader.nextRecord()) != null) { // 取出字段信息 p_read.rtnCheckColFieldValue.clear(); for (int i = 0; i < p_read.rtnFieldsCount; i++) { // 獲取DBF字段信息 DBFField field = p_read.rtnReader.getField(i); String fieldName = JavaUtil.toUpperCase(JavaUtil.trim(field.getName())); Object fieldValue = rowValue[i]; p_read.rtnCheckColFieldValue.put(fieldName, fieldValue); } // 用此rtnCheckColFieldValue鍵值進行判斷 int checkRow = p_read.checkRow(); if (p_read.BREAK == checkRow) { break; } if (p_read.CONTINUE == checkRow) { continue; } if (p_read.OK != checkRow) { throw new ServiceException("返回值只支持[OK、CONTINUE、BREAK]"); } // 實例化一行行值 Map<String, Object> rowValues = new HashMap<String, Object>(); // 添加一行記錄值 p_read.rtnRowFieldValues.add(rowValues); p_read.rtnRowValues.add(rowValue); // 取出字段信息 for (int i = 0; i < p_read.rtnFieldsCount; i++) { // 獲取DBF字段信息 DBFField field = p_read.rtnReader.getField(i); String fieldName = JavaUtil.toUpperCase(JavaUtil.trim(field.getName())); Object fieldValue = rowValue[i]; // // 轉換值Double->String // if (fieldValue instanceof Double) { // java.text.DecimalFormat df = new java.text.DecimalFormat(); // df.setGroupingUsed(false); // fieldValue = df.format(fieldValue); // } // 添加一行行值 rowValues.put(fieldName, fieldValue); // 添加對應的鍵值數據 List<Object> values = p_read.rtnColFieldValues.get(fieldName); if (values == null) { values = new ArrayList<Object>(); p_read.rtnColFieldValues.put(fieldName, values); } // 添加值 values.add(fieldValue); // System.out.print(fieldName + ":" + fieldValue + "\t"); } // System.out.println(); } } catch (Exception e) { throw new ServiceException(e); } finally { try { fis.close(); } catch (Exception e) { } } } /** * 通用寫dbf文件 * * @param p_path * DBF文件路徑 * @param p_fields * 字段值,下面4個字段必須填寫 * @see {@link com.linuxense.javadbf.DBFField#setFieldLength(int)}; * @see {@link com.linuxense.javadbf.DBFField#setDecimalCount(int)}}; * @see {@link com.linuxense.javadbf.DBFField#setName(String)}; * @see {@link com.linuxense.javadbf.DBFField#setDataType(byte)}; * @see byte:{@link com.linuxense.javadbf.DBFDataType#類型}(byte code, int minSize, int maxSize, int defaultSize, boolean writeSupported) * @see byte:{@link com.linuxense.javadbf.DBFDataType#CHARACTER}('C', 1, 254, 0, true) * @see byte:{@link com.linuxense.javadbf.DBFDataType#DATE}('D', 8, 8, 8, true) * @see byte:{@link com.linuxense.javadbf.DBFDataType#FLOATING_POINT}('F', 1, 20, 0, true) * @see byte:{@link com.linuxense.javadbf.DBFDataType#LOGICAL}('L', 1, 1, 1, true) * @see byte:{@link com.linuxense.javadbf.DBFDataType#NUMERIC}('N', 1, 32, 0, true) * * @param p_rowValues * 行值 */ public static void writeDBF(DBFWrite p_write) { OutputStream fos = null; try { if (CheckUtil.isNull(p_write.paramPath)) { throw new ServiceException("paramPath:文件路徑不能為空"); } // 創建文件對應的上級目錄 File v_pfile = new File(FileUtil.getParentPath(p_write.paramPath)); if (!v_pfile.exists()) { v_pfile.mkdirs(); } if (p_write.paramRead != null) { // 自動賦值 p_write.paramFields = p_write.paramRead.rtnFields; p_write.paramRowValues = p_write.paramRead.rtnRowValues; } // 定義DBF文件字段 int v_columnSize = p_write.paramFields.size(); // 轉換為list好操作 List<DBFField> v_fieldList = new ArrayList<DBFField>(); // 添加列 for (int i = 0; i < v_columnSize; i++) { try { DBFField r_field = p_write.callbackResetField(p_write.paramFields.get(i)); if (r_field == null) { continue; } v_fieldList.add(r_field); } catch (Exception e) { // 異常退出 logger.error("設置字段異常,中斷循環", e); break; } } // 最終的字段 v_fieldList = p_write.callbackResetFields(v_fieldList); DBFField[] v_fields = JavaUtil.listToArray(v_fieldList, DBFField.class); // 定義DBFWriter實例用來寫DBF文件 // 定義輸出流,并關聯的一個文件 fos = new BufferedOutputStream(new FileOutputStream(p_write.paramPath)); DBFWriter writer = new DBFWriter(fos, p_write.paramCharset); // 把字段信息寫入DBFWriter實例,即定義表結構 writer.setFields(v_fields); for (Object[] v_rowValue : p_write.paramRowValues) { try { List<Object> p_rowValue = Arrays.asList(v_rowValue); // 不執行下面方法,則報:java.lang.UnsupportedOperationException p_rowValue = new ArrayList<Object>(p_rowValue); // System.out.println("old:" + p_rowValue.size()); // 如果不想改變p_rowValue值,則使用JavaUtil.deepCopy(p_rowValue)深度拷貝list List<Object> r_rowValue = p_write.callbackResetRowValue(v_fieldList, p_rowValue); if (r_rowValue == null) { continue; } // System.out.println("new:" + p_rowValue.size()); writer.addRecord(JavaUtil.listToArray(r_rowValue, Object.class)); } catch (Exception e) { // 異常退出 logger.error("設置值異常,中斷循環", e); break; } } // 寫入數據 writer.close(); } catch (Exception e) { throw new ServiceException(e); } finally { try { fos.close(); } catch (Exception e) { } } } /** * 導出DBF文件 * * @param p_titles * 標題,格式為,名稱|類型|長度|精度 * @param p_listValues * 值 * @param dbfFile * DBF文件 */ public static void exportDBF(List<String> p_titles, List<Object[]> p_listValues, File dbfFile) { exportDBF(null, p_titles, p_listValues, dbfFile); } /** * 導出DBF文件 * * @param write * DBF寫入對象 * @param p_titles * 標題,格式為,名稱|類型|長度|精度 * @param p_listValues * 值 * @param dbfFile * DBF文件 */ public static void exportDBF(DBFWrite write, List<String> p_titles, List<Object[]> p_listValues, File dbfFile) { if (write == null) write = new DBFWrite(); for (String v_title : p_titles) { String[] v_titleAry = JavaUtil.split(v_title, "|"); String name = ""; // 默認字符 char type = 'C'; // 默認長度為100 int length = 0; int decimalCount = 0; if (v_titleAry.length == 1) { // 默認字符 name = v_titleAry[0]; } else if (v_titleAry.length == 2) { name = v_titleAry[0]; type = JavaUtil.toUpperCase(v_titleAry[1]).toCharArray()[0]; } else if (v_titleAry.length == 3) { name = v_titleAry[0]; type = JavaUtil.toUpperCase(v_titleAry[1]).toCharArray()[0]; length = TypeUtil.Primitive.intValue(v_titleAry[2]); } else if (v_titleAry.length == 4) { name = v_titleAry[0]; type = JavaUtil.toUpperCase(v_titleAry[1]).toCharArray()[0]; length = TypeUtil.Primitive.intValue(v_titleAry[2]); decimalCount = TypeUtil.Primitive.intValue(v_titleAry[3]); } // System.out.println(name + "," + type + "," + length + "," + decimalCount); if (length == 0) { // 一般由自己根據情況定義 length = write.defaultSize; } write.paramFields.add(new DBFField(name, DBFDataType.fromCode(type), length, decimalCount)); } // List<Map<String, Object>> v_listMap = queryResult.rtnDatas; // System.out.println(v_listMap); // for (Map<String, Object> v_map : v_listMap) { // System.out.println(v_map); // } // System.out.println(p_listValues); // for (Object[] v_listValue : p_listValues) { // System.out.println(Arrays.toString(v_listValue)); // } write.paramRowValues = p_listValues; write.paramPath = dbfFile; writeDBF(write); } }
本文為張軍原創文章,轉載無需和我聯系,但請注明來自張軍的軍軍小站,個人博客http://m.eyofj.com
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
