content: package access2csv;
  
  import java.io.BufferedWriter;
  import java.io.File;
  import java.io.FileNotFoundException;
  import java.io.FileWriter;
  import java.io.IOException;
  import java.io.PrintWriter;
  import java.io.Writer;
  import java.util.Arrays;
  import java.util.List;
  
  import com.opencsv.CSVWriter;
  
  import joptsimple.OptionException;
  import joptsimple.OptionParser;
  import joptsimple.OptionSet;
  import joptsimple.OptionSpec;
  
  import com.healthmarketscience.jackcess.*;
  
  public class Driver {
  
    
  	static int export(Database db, String tableName, Writer csv, boolean withHeader, boolean applyQuotesToAll, String nullText) throws IOException{
  		Table table = db.getTable(tableName);
  		String[] buffer = new String[table.getColumnCount()];
  		CSVWriter writer = new CSVWriter(new BufferedWriter(csv), CSVWriter.DEFAULT_SEPARATOR, CSVWriter.DEFAULT_QUOTE_CHARACTER);
  		int rows = 0;
  		try{
  			if (withHeader) {
  				int x = 0;
  				for(Column col : table.getColumns()){
  					buffer[x++] = col.getName();
  				}
  				writer.writeNext(buffer, applyQuotesToAll);
  			}
              
  			for(Row row : table){
  				int i = 0;
  				for (Object object : row.values()) {
  					buffer[i++] = object == null ? nullText : object.toString();
  				}
  				writer.writeNext(buffer, applyQuotesToAll);
  				rows++;
  			}
  		}finally{
  			writer.close();
  		}
  		return rows;
  	}
  
  	static void export(File inputFile, String tableName, boolean withHeader, File outputDir, String csvPrefix, boolean applyQuotesToAll, String nullText) throws IOException{
  		Database db = DatabaseBuilder.open(inputFile);
  		try{
  			export(db, tableName, new FileWriter(new File(outputDir, csvPrefix + tableName + ".csv")), withHeader, applyQuotesToAll, nullText);
  		}finally{
  			db.close();
  		}
  	}
  
  	static void schema(File inputFile) throws IOException{
  
  		Database db = DatabaseBuilder.open(inputFile);
  		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(File inputFile, boolean withHeader, File outputDir, String csvPrefix, boolean applyQuotesToAll, String nullText) throws IOException{
  		Database db = DatabaseBuilder.open(inputFile);
  		try{
  			for(String tableName : db.getTableNames()){
  				String csvName = csvPrefix + tableName + ".csv";
  				File outputFile = new File(outputDir, csvName);
  				Writer csv = new FileWriter(outputFile);
  				try{
  					System.out.println(String.format("Exporting '%s' to %s",
  							tableName, outputFile.toString()));
  					int rows = export(db, tableName, csv, withHeader, applyQuotesToAll, nullText);
  					System.out.println(String.format("%d rows exported", rows));
  				}finally{
  					try{
  						csv.flush();
  						csv.close();
  					}catch(IOException ex){}
  				}
  			}
  		}finally{
  			db.close();
  		}
  
  	}
  
  	public static void main(String[] args) throws Exception {
  		final OptionParser parser = new OptionParser();
  
  		final OptionSpec<Void> help = parser.acceptsAll(Arrays.asList("help")).forHelp();
  		final OptionSpec<String> schema = parser.accepts("schema").withOptionalArg()
  				.describedAs("The schema is written to standard output.");
  		final OptionSpec<String> withHeader = parser.accepts("with-header").withOptionalArg()
  				.describedAs("When with-header is included, a header line of column names is written to each data file.");
  		final OptionSpec<File> input = parser.accepts("input").withRequiredArg().ofType(File.class).required()
  				.describedAs("The input accdb file.");
  		final OptionSpec<String> table = parser.accepts("table").withRequiredArg().ofType(String.class).describedAs("The table name to export, or all if it is not specified.");
  		final OptionSpec<File> output = parser.accepts("output").requiredUnless("schema").withRequiredArg().ofType(File.class)
  				.describedAs("The output directory for data files. This is required for writing data output. This not required for schema output.");
  		final OptionSpec<String> csvPrefix = parser.accepts("csv-prefix").withRequiredArg().ofType(String.class).defaultsTo("").describedAs("A prefix to add to all of the generated CSV file names");    
  		final OptionSpec<Boolean> quoteAll = parser.accepts("quote-all").withOptionalArg().ofType(Boolean.class).defaultsTo(true)
  				.describedAs("Set quote-all to true if all values are to be quoted. " +
  				"Set to false if quotes are only to be applied to values which contain " + 
  				"the separator, secape, quote, or new line characters. The default is true.");
  		final OptionSpec<String> writeNull = parser.accepts("write-null").withOptionalArg().ofType(String.class).defaultsTo("")
  				.describedAs("The text to write when entry is NULL. Defaults to empty output if not specified or if no argument supplied. " +
  				"If quote-all is set to true then the value for write-null is also quoted.");
     
      
  		OptionSet options = null;
  
  		try {
  			options = parser.parse(args);
  		} catch (final OptionException e) {
  			System.out.println(e.getMessage());
  			parser.printHelpOn(System.out);
  			throw e;
  		}
  
  		if (options.has(help)) {
  			parser.printHelpOn(System.out);
  			return;
  		}
        
  		File inputFile = input.value(options);
  		if(!inputFile.exists()) {
  			throw new FileNotFoundException("Could not find input file: " + inputFile.toString());
  		}
  		
  		File outputDir = null;
  		if (options.has(output)) {
  			outputDir = output.value(options);
  			if(!outputDir.exists()) {
  				outputDir.mkdirs();
  			}	
  		}
      		
  		boolean applyQuotesToAll = quoteAll.value(options);    
      String nullText = writeNull.value(options);
      
  		if (options.has(schema)) {
  			schema(inputFile);
  		}
  		
  		if (null != outputDir) {
  			if (options.has(table)){
  				export(inputFile, table.value(options), options.has(withHeader), outputDir, csvPrefix.value(options), applyQuotesToAll, nullText);
  			}
  			else {
  				exportAll(inputFile, options.has(withHeader), outputDir, csvPrefix.value(options), applyQuotesToAll, nullText);
  			}	
  		}
  	}
  
  }
  