content: package access2csv;
  
  import java.io.BufferedWriter;
  import java.io.File;
  import java.io.FileWriter;
  import java.io.IOException;
  import java.io.PrintWriter;
  import java.io.Writer;
  import java.util.Arrays;
  import java.util.ArrayList;
  import java.util.List;
  
  import com.opencsv.CSVWriter;
  
  import com.healthmarketscience.jackcess.*;
  
  public class Driver {
  
  	static int export(Database db, String tableName, Writer csv, boolean withHeader) throws IOException{
  		Table table = db.getTable(tableName);
  		String[] buffer = new String[table.getColumnCount()];
  		CSVWriter writer = new CSVWriter(new BufferedWriter(csv));
  		int rows = 0;
  		try{
  			if (withHeader) {
  				int x = 0;
  				for(Column col : table.getColumns()){
  					buffer[x++] = col.getName();
  				}
  				writer.writeNext(buffer);
  			}
  
  			for(Row row : table){
  				int i = 0;
  				for (Object object : row.values()) {
  					buffer[i++] = object == null ? null : object.toString();
  				}
  				writer.writeNext(buffer);
  				rows++;
  			}
  		}finally{
  			writer.close();
  		}
  		return rows;
  	}
  	
  	static Database openDatabase( String filename, String db_passwd ) throws IOException{
  		if( db_passwd.equals("")) {
  			Database db = DatabaseBuilder.open(new File(filename));
  			return( db ) ;
  		} else {
  			Database db = new DatabaseBuilder(new File(filename))
  				.setCodecProvider(new CryptCodecProvider(db_passwd))
  				.open();
  			return( db ) ;
  		}
  	}
  
  	static void export(String filename, String tableName, boolean withHeader, String db_passwd) throws IOException{
  		Database db = openDatabase( filename, db_passwd ) ;
  		
  		try{
  			export(db, tableName, new PrintWriter(System.out), withHeader);
  		}finally{
  			db.close();
  		}
  	}
  
  	static void schema(String filename, String db_passwd) throws IOException{
  		Database db = openDatabase( filename, db_passwd ) ;
  
  		try{
  			for(String tableName : db.getTableNames()){
  				Table table = db.getTable(tableName);
  				System.out.println(String.format("CREATE TABLE %s (", tableName));
  				for(Column col : table.getColumns()){
  					System.out.println(String.format("  %s %s,", 
  							col.getName(), col.getType()));
  				}
  				System.out.println(")");
  			}
  		}finally{
  			db.close();
  		}
  
  	}
  
  	static void exportAll(String filename, boolean withHeader, String db_passwd) throws IOException{
  		Database db = openDatabase( filename, db_passwd ) ;
  
  		try{
  			for(String tableName : db.getTableNames()){
  				String csvName = tableName + ".csv";
  				Writer csv = new FileWriter(csvName);
  				try{
  					System.out.println(String.format("Exporting '%s' to %s/%s",
  							tableName, System.getProperty("user.dir"), csvName));
  					int rows = export(db, tableName, csv, withHeader);
  					System.out.println(String.format("%d rows exported", rows));
  				}finally{
  					try{
  						csv.flush();
  						csv.close();
  					}catch(IOException ex){}
  				}
  			}
  		}finally{
  			db.close();
  		}
  
  	}
  
  	static void printUsage(){
  		System.out.println("Usage:");
  		System.out.println(" java -jar access2csv.jar [ACCESS FILE] [OPTIONS]");
  		System.out.println("");
  		System.out.println("Options:");
  		System.out.println("");
  		System.out.println(" * if no options are provided, all tables will be exported to CSV files,");
  		System.out.println("   one file per table. Output file paths will be printed to stdout");
  		System.out.println(" * '--password password' - tries to open an encrypted database with the specified password");
  		System.out.println(" * '--schema' - prints the database schema");
  		System.out.println(" * '--with-header' - export the header with the field names");
  		System.out.println(" * [TABLENAME] - prints the given table as CSV to stdout");
  	}
  
  	/**
  	 * @param args
  	 * @throws IOException 
  	 */
  	public static void main(String[] cmdLineArgs) throws IOException {
  		List<String> helpCommands = Arrays.asList(new String[]{"-h", "--help", "-H", "/?"});
  		List<String> passwdCommands = Arrays.asList(new String[]{"-p", "--password", "--passwd"});
  		
  		// Make a copy of the command line args and then
  		// process them to remove and record any passwords
  		// and note any --with-header options
  		String password = "" ;
  		boolean includeHeaders = false ; // the default
  		List<String> argList = new ArrayList<>() ;
  		for( int j=0 ; j < cmdLineArgs.length ; j++ ) {
  			if( passwdCommands.contains(cmdLineArgs[j]) ) {
  				if( ++j < cmdLineArgs.length ) {
  					password = cmdLineArgs[j] ;
  				} else {
  					printUsage();
  					System.exit(0);
  				}
  			} 
  			else if( cmdLineArgs[j].equals("--with-header") ) {
  				includeHeaders = true ;
  			}
  			else {
  				// Save the arg to handle later
  				argList.add( cmdLineArgs[j] ) ;
  			}
  		}
  				
  		// Copy argList into an array so that the block below will work
  		String[] args = argList.toArray(new String[argList.size()]) ;
  		
  		// Handle remaining args
  		if( args.length == 1 ) {
  			if( helpCommands.contains(args[0]) ){
  				printUsage();
  			}
  			else {
  				exportAll(args[0], includeHeaders, password);
  			}
  			
  			System.exit(0);
  		}
  		else if( args.length == 2 ) {
  			if( args[1].equals("--schema") ){
  				schema(args[0], password) ;
  			}
  			else {
  				export(args[0], args[1], includeHeaders, password);
  			}
  			
  			System.exit(0) ;
  		}
  		else {
  			System.err.println("Invalid arguments.");
  			printUsage();
  			System.exit(1);
  		}
  	}
  }
  