Пакетное преобразование визуальных таблиц foxpro dbf в csv - PullRequest
2 голосов
/ 13 января 2012

У меня есть огромная коллекция визуальных файлов foxpro dbf, которые я хотел бы преобразовать в csv. (Если хотите, вы можете загрузить некоторые данные здесь . Нажмите на ссылку 2011 года для данных транзакции и приготовьтесь долго ждать ...)

Я могу открыть каждую таблицу с помощью DBF View Plus (потрясающая бесплатная утилита), но экспорт их в CSV занимает несколько часов на файл, и у меня есть несколько десятков файлов для работы.

Существует ли такая программа, как DBF View plus, которая позволит мне настроить пакетное преобразование dbf-to-csv для выполнения в одночасье?

/ Edit: в качестве альтернативы, есть ли хороший способ импортировать файлы .dbf прямо в SQL Server 2008? Все они должны входить в 1 таблицу, поскольку каждый файл является просто подмножеством записей из одной таблицы и должен иметь одинаковые имена столбцов.

Ответы [ 4 ]

5 голосов
/ 13 января 2012

Загрузите ваш список файлов FoxPro в массив / список, затем вызовите ConvertDbf для каждого из них, чтобы преобразовать их из FoxPro в CSV-файлы. См. Код консольного приложения c # ниже ...

Кредит c # с датой csv для функции DataTableToCSV.

using System;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Text;

namespace SO8843066
{
    class Program
    {
        static void Main(string[] args)
        {
            string connectionString = @"Provider=VFPOLEDB.1;Data Source=C:\";
            string dbfToConvert = @"C:\yourdbffile.dbf";
            ConvertDbf(connectionString, dbfToConvert, dbfToConvert.Replace(".dbf", ".csv"));

            Console.WriteLine("End of program execution");
            Console.WriteLine("Press any key to end");
            Console.ReadKey();
        }

        static void DataTableToCSV(DataTable dt, string csvFile)
        {
            StringBuilder sb = new StringBuilder(); 
            var columnNames = dt.Columns.Cast<DataColumn>().Select(column => column.ColumnName).ToArray(); 
            sb.AppendLine(string.Join(",", columnNames)); 
            foreach (DataRow row in dt.Rows) 
            { 
                var fields = row.ItemArray.Select(field => field.ToString()).ToArray(); 
                for (int i =0;i < fields.Length;i++)
                {
                    sb.Append("\"" + fields[i].Trim() );
                    sb.Append((i != fields.Length - 1) ? "\"," : "\"");
                }
                sb.Append("\r\n");
            } 
            File.WriteAllText(csvFile, sb.ToString());
        }

        static void ConvertDbf(string connectionString, string dbfFile, string csvFile)
        {
            string sqlSelect = string.Format("SELECT * FROM {0}", dbfFile);
            using (OleDbConnection connection = new OleDbConnection(connectionString))
            {
                using (OleDbDataAdapter da = new OleDbDataAdapter(sqlSelect, connection))
                {
                    DataSet ds = new DataSet();
                    da.Fill(ds);
                    DataTableToCSV(ds.Tables[0], csvFile);
                }
            }
        }
    }
}
2 голосов
/ 17 апреля 2015

Это работает очень хорошо, и спасибо за решение.Я использовал это для преобразования некоторых визуальных таблиц foxpro dbf в плоские файлы.С этими таблицами возникает дополнительная проблема преобразования полей типа Валюта.Поля валюты представляют собой 64-разрядное (8-байтовое) целое число со знаком среди массива байтов из 36 элементов, начиная с 27-й позиции.Затем целое число делится на 1000, чтобы получить эквивалент с 4 десятичной точностью.

Если у вас есть этот тип поля, попробуйте это внутри полей цикла FOR

if (("" + fields[i]).Equals("System.Byte[]"))
{
    StringBuilder db = new StringBuilder();
    byte[] inbytes = new byte[36];
    inbytes = ObjectToByteArray(fields[i]);
    db.Append("" + (double)BitConverter.ToInt64(inbytes,27)/1E4);
    sb.Append("\"" + db);
}

С помощью следующего вспомогательного метода

private static byte[] ObjectToByteArray(Object obj)
    {
        BinaryFormatter bf = new BinaryFormatter();
        using (var ms = new MemoryStream())
        {
            bf.Serialize(ms, obj);
            return ms.ToArray();
        }
    }
2 голосов
/ 13 января 2012

В этом случае SQL-Server, я думаю, имеет возможность подключения к таблицам foxpro. Я не совсем уверен, как, поскольку я никогда не делал этого в последнее время (в последний раз, используя SQL-сервер около 8 лет назад). Я уверен, что есть другие потоки, которые могут указать вам на подключение SQL-Server к VFP.

Я быстро искал и увидел эту тему

Кроме того, вам может потребоваться последний поставщик OleDb, чтобы установить соединение, которое я также разместил в теме здесь . В этом потоке также показан пример информации о строке подключения, которая может понадобиться вам от SQL-Server. Информация об источнике данных должна указывать на ПУТЬ, где находятся файлы .DBF, а не на конкретное имя .DBF, к которому вы пытаетесь подключиться.

Надеюсь, это поможет вам.

1 голос
/ 13 января 2012
...