Skip to content

Instantly share code, notes, and snippets.

@drmalex07
Created November 3, 2018 17:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drmalex07/9cadcd2db2121043e5363afca237d766 to your computer and use it in GitHub Desktop.
Save drmalex07/9cadcd2db2121043e5363afca237d766 to your computer and use it in GitHub Desktop.
Convert a DBF file to CSV using Java. #dbf #csv #java
package com.example.scratch_java;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.jamel.dbf.DbfReader;
import org.jamel.dbf.structure.DbfHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DbfToCsv
{
private static final Logger logger = LoggerFactory.getLogger(DbfToCsv.class);
public static void main(String[] args) throws IOException
{
if (args.length < 2) {
System.err.println("Usage: java DbfToCsv <dbf-path> <output-path>");
System.exit(0);
}
final Path dbfPath = Paths.get(args[0]);
final Path outputPath = Paths.get(args[1]);
logger.info("Reading DBF database from {}", dbfPath);
logger.info("Writing CSV data to {}", outputPath);
convertDbfToCsv(dbfPath, outputPath);
}
private static Function<Object,String> converterForDataType(char typecode, final Charset cs)
{
Function<Object,String> converter = null;
switch (typecode) {
case 'D':
converter = date -> ((Date) date).toInstant().toString();
break;
case 'C':
converter = cdata -> (new String((byte[]) cdata, cs)).trim();
break;
case 'F':
case 'N':
converter = String::valueOf;
break;
default:
throw new IllegalArgumentException(
"Encountered an unknown typecode [" + typecode + "]");
}
return converter;
}
public static void convertDbfToCsv(Path dbfPath, Path outputPath) throws IOException
{
final Charset inputCharset = Charset.forName("UTF-8");
final Charset charset = Charset.forName("UTF-8");
try (DbfReader reader = new DbfReader(dbfPath.toFile());
CSVPrinter csvPrinter = new CSVPrinter(Files.newBufferedWriter(outputPath, charset), CSVFormat.RFC4180))
{
final DbfHeader dbfHeader = reader.getHeader();
final int fieldCount = dbfHeader.getFieldsCount();
final List<Function<Object,String>> fieldConverter = IntStream.range(0, fieldCount)
.map(i -> (char) dbfHeader.getField(i).getDataType())
.mapToObj(code -> converterForDataType((char) code, inputCharset))
.collect(Collectors.toList());
final List<String> fieldNames = IntStream.range(0, fieldCount)
.mapToObj(i -> dbfHeader.getField(i).getName())
.collect(Collectors.toList());
// Print CSV header
csvPrinter.printRecord(fieldNames);
// Print CSV data
Object[] row = null;
while ((row = reader.nextRecord()) != null) {
for (int fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex) {
String fieldData = fieldConverter.get(fieldIndex).apply(row[fieldIndex]);
csvPrinter.print(fieldData);
}
csvPrinter.println();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment