Java解析之纠结的DBF文件_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Java解析之纠结的DBF文件

Java解析之纠结的DBF文件

 2013/9/12 18:52:40  qindongliang1922  程序员俱乐部  我要评论(0)
  • 摘要:明天,持续更新Lucene系列博文,欢迎收看!Lucene群交流:324714439下面进入正题最近客户提了个新的需求,需要我们的程序支持如下几种文件的解析编号文件格式1XML2Excel3Access4DBF5MDB可能有些朋友,不知道DBF这种格式的文件是什么东西,在这之前,散仙,先小小科普下这种古董级的数据库格式,来看下百度百科是怎么介绍的。一种特殊的文件格式!表示数据库文件,Foxbase,Dbase,VisualFoxPro,等数据库处理系统所产生的数据库文件
  • 标签:文件 Java 解析
   
    明天,持续更新Lucene系列博文,欢迎收看!
  Lucene群交流:324714439

下面进入正题


最近客户提了个新的需求,需要我们的程序支持如下几种文件的解析
编号文件格式1XML2Excel3Access4DBF5MDB
可能有些朋友,不知道DBF这种格式的文件是什么东西,在这之前,散仙,先小小科普下这种古董级的数据库格式,来看下百度百科是怎么介绍的。

一种特殊的文件格式!表示数据库文件,Foxbase,Dbase,Visual FoxPro,等数据库处理系统所产生的数据库文件!
DBF 数据库可以分为 dBase III 、foxpro 格式两类。
DBF 数据库是常用的桌面型数据库,它曾经被各企业、事业单位广泛使用。现在,虽然已经有了很多的各种各样的小、中、大型数据库,DBF 数据库依然被很多单位用于数据交换。

下面我们来看下Foxbase DBF的截图.





DBF,以及Access都是微软支持的数据库产品,解析时使用jdbc-odbc桥接的方式,可以很方便解析。
关于MDB,其实是SQL Server分离后的数据库,这个直接可以直接导入数据库使用,然后使用Java的JDBC读取即可,这个需求很简单,散仙在这里就不用多演示了,下面,我们来重点看下其他4种文件的Java解析方法




1.解析XML,散仙使用的是jdom2,解析起来也比较方便快捷,XML格式如下


核心代码如下

class="java">File f = new File("E:\\data\\test.xml");              
				 Document doc=sax.build(f);//解析file的xml文件
				 Element root=doc.getRootElement();//获取根节点
				 List<Element> eles= root.getChildren();//获取根节点下面子节点的集合
				// System.out.println(eles.size());
				 List<XmlEntity> xmls=new ArrayList<XmlEntity>();
				 for(Element e:eles){
					 String ui=e.getChildText("ui");
					 String ti=e.getChildText("ti");
					 String ta=e.getChildText("ta");
					 String dp=e.getChildText("dp");
					 String vi=e.getChildText("vi");
					 String ip=e.getChildText("ip");
					 String pg=e.getChildText("pg");
					 String mh=e.getChildText("mh");
					 xmls.add(new XmlEntity(ui, ti, ta, dp, vi, ip, pg, mh));
//					 System.out.println(e.getChildText("ui"));
//					 System.out.println(e.getChildText("ti"));
//					 System.out.println(e.getChildText("ta"));
//					 System.out.println(e.getChildText("dp"));
//					 System.out.println(e.getChildText("vi"));
//					 System.out.println(e.getChildText("ip"));
//					 System.out.println(e.getChildText("pg"));
//					 System.out.println(e.getChildText("mh"));
					 
					// System.out.println("=================================");
					 
				 }
				 DAO.add(xmls);//持久化到数据库中
				 System.out.println("添加成功!");
				 // System.out.println("获取根节点的名字 :"+root.getName());
			 



2,使用POI解析Excel,格式如下



核心代码如下

/**
	 * 判断单元格格式
	 * **/
	 private static String getCellValue(HSSFCell cell) {  
	        String cellValue = "";  
	        DecimalFormat df = new DecimalFormat("#");  
	       
	        switch (cell.getCellType()) {  
	        case HSSFCell.CELL_TYPE_STRING:  
	            cellValue = cell.getRichStringCellValue().getString().trim();  
	            break;  
	        case HSSFCell.CELL_TYPE_NUMERIC:  
	            cellValue = df.format(cell.getNumericCellValue()).toString();  
	            break;  
	        case HSSFCell.CELL_TYPE_BOOLEAN:  
	            cellValue = String.valueOf(cell.getBooleanCellValue()).trim();  
	            break;  
	        case HSSFCell.CELL_TYPE_FORMULA:  
	            cellValue = cell.getCellFormula();  
	            break;  
	        default:  
	            cellValue = "";  
	        }  
	        return cellValue;  
	    } 


 /**
	  * 读取Excel
	  * **/
	 public static List<ExcelEntity> readExcel(String filePath) throws Exception {

		  FileInputStream fis = new FileInputStream(filePath); // 根据excel文件路径创建文件流
		  POIFSFileSystem fs = new POIFSFileSystem(fis); // 利用poi读取excel文件流
		  HSSFWorkbook wb = new HSSFWorkbook(fs); // 读取excel工作簿
		  HSSFSheet sheet = wb.getSheetAt(0); // 读取excel的sheet,0表示读取第一个、1表示第二个.....

		  // 获取sheet中总共有多少行数据sheet.getPhysicalNumberOfRows()
		//  System.out.println(sheet.getPhysicalNumberOfRows());
		  List<ExcelEntity> excels=new ArrayList<ExcelEntity>();
		  for (int i = 0; i < sheet.getPhysicalNumberOfRows(); i++) {
		   HSSFRow row = sheet.getRow(i+1); //忽略首行,标题行            取出sheet中的某一行数据
		   if (row != null) {
		    // 获取该行中总共有多少列数据row.getLastCellNum()
			   
			   ExcelEntity excel=new ExcelEntity();
			   HashMap<Integer, String> map=new HashMap<>();
		    for (int j = 0; j < row.getLastCellNum(); j++) {
		    	//System.out.println(row.getLastCellNum());
		    	//System.exit(0);
		     HSSFCell cell = row.getCell(j); // 获取该行中的一个单元格对象
		    if(cell==null){
		    	cell=row.createCell(j);//如果某个单元格为空的话,就创建一个,否则会报异常
		    }
		   String str=   getCellValue(cell);
		   map.put(j, str);
		  // System.out.println(str);
		     
		     //}
		    }

 



3,使用JDBC-ODBC桥接方式读取Access文件,使用Acces
与DBF都需要配置桥接模式,在控制面板里,选择管理工具里配置



核心代码如下,
	try {
				Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
				con = DriverManager.getConnection("jdbc:odbc:ss",  bulidPath, "");//加载驱动,默认密码,空字符串即可
				//System.out.println("Access连接:"+con);
			} catch (Exception e) {
				e.printStackTrace();
			}


AccessBase ab=new AccessBase();
	 Connection con=ab.getConnection("zdbz.mdb");
	 String sql="select * from test";//查询表
	 PreparedStatement ps=con.prepareStatement(sql);
	 ResultSet rs=ps.executeQuery();
	  //ResultSetMetaData s=rs.getMetaData();
	 // int i=s.getColumnCount();
	  //System.out.println(i);
	 List<ExcelEntity> list=new ArrayList<ExcelEntity>();
	  while(rs.next()){
		ExcelEntity xml=new ExcelEntity();
		 xml.setUi(rs.getString(1));
		 xml.setTi(rs.getString(2));
		 xml.setTa(rs.getString(3));
		 xml.setDp(rs.getString(4));
		 xml.setVi(rs.getString(5));
		 xml.setIp(rs.getString(6));
		 xml.setPg(rs.getString(7));
		 xml.setAb(rs.getString(8));
		 xml.setKw(rs.getString(9));
		 xml.setMh(rs.getString(10));
		 list.add(xml);
	 
		 
	  }
	 
	  
	  DAO.addAccess(list);
	 // System.out.println(i);
	  rs.close();
	  ps.close();
	  con.close();


4,最后在来说一下,比较纠结的DBF的解析,关于这个东西,散仙以前也没用过,现在客户有这种需求,自然得做好,于是乎Google了一把,效果似乎还不错,第一页上基本全是有关于,JAVA解析DBF格式的,当时我还在想,得来全不费工夫,于是,找了一篇,看起来似乎挺靠谱的解析博客,拷贝了其中的代码,拿过来使用,结果报了各种异常,这种方式是用流读取的,然后直接解析流,提取每一行数据,还附带一个jar包,散仙后面会把jar给传上来,我们先看下这种方式的代码:

package com.dbhelper;

import java.io.FileInputStream;
import java.io.InputStream;

import com.hexiong.jdbf.DBFReader;

 
 

 

public class ParseDBF {
	
	public static void main(String[] args) {
		
		readDBF("C:\\Users\\cuichao\\Desktop\\zdbz\\test.DBF");
	}

	public static void readDBF(String path)

	{

		InputStream fis = null;

		try

		{

			// 读取文件的输入流

			fis = new FileInputStream(path);

			// 根据输入流初始化一个DBFReader实例,用来读取DBF文件信息
            
			 DBFReader reader = new DBFReader(fis);
		  
			//DBFReader reader=new DBFReader("C:\\Users\\cuichao\\Desktop\\zdbz\\test.DBF");
              // System.out.println(reader);
			// 调用DBFReader对实例方法得到path文件中字段的个数

			int fieldsCount = reader.getFieldCount();
             System.out.println(fieldsCount);
	
             Object[] s= reader.nextRecord();
             
              while(reader.nextRecord()!=null&&reader.nextRecord().length>0){
             	 
            	  for(int i=0;i<reader.nextRecord().length;i++){
            		  System.out.println(reader.nextRecord()[i]);
            		  
            	  }
              }
		}

		catch (Exception e)

		{

			e.printStackTrace();

		}

		finally

		{

			try {

			//	fis.close();

			} catch (Exception e) {
			}

		}

	}

}


这种流读取的方式,散仙也看了下源码,代码比较繁琐,而且有好多限制不能用,比如说,读取某列的字符长度不能大于8,或者包含某个C或D的字符的不能用,等等。散仙,猜想这个发博客的人,是根据自己的业务定义的,这也不能怪人家,各个业务的需求都不一样,难免会出现这种情况。 下面,我们来看看,最王道,最通用的解析方法, 既然,它是数据库,那么我们为什么不按数据库的方式来搞呢? 用流读取的方式,不通用,而且异常百出,按数据库的方式,解决,才是最完美的方法。

首先配置好的桥接,截图如下




核心代码如下

    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");//加载驱动
		 	            try {
		 	                //conn = DriverManager.getConnection(DB_URL);
		 	                conn = DriverManager.getConnection("jdbc:odbc:ss","test.dbf","");//无密码则空字符串
		 	                pstm = conn.prepareStatement("select * from test"); // 此处的XXB 为DBF数据文件的名字
		 	 
		 	                rs = pstm.executeQuery();


至此,完美解决DBF数据库文件读取。网上的东西,太杂了,所以,我们要理智判断,取其精华,去其糟粕,为我所用。


  • 大小: 95.1 KB
  • 大小: 137.4 KB
  • 大小: 55.1 KB
  • 大小: 58.4 KB
  • 大小: 64.5 KB
  • dbf.jar (14.1 KB)
  • 下载次数: 0
  • jdom-2.0.4.jar (291.4 KB)
  • 下载次数: 0
  • poi-3.9-20121203.jar (1.8 MB)
  • 下载次数: 0
  • 查看图片附件
发表评论
用户名: 匿名