Объединить несколько CSV в один без использования Excel.Application - PullRequest
0 голосов
/ 06 ноября 2018

Я создал скрипт PowerShell, который позволяет мне объединять несколько файлов .CSV в один файл .XLSX.

Хорошо работает на моем компьютере:

$path = "C:\Users\Francesco\Desktop\CSV\Results\*"
$csvs = Get-ChildItem $path -Include *.csv
$y = $csvs.Count
Write-Host "Detected the following CSV files: ($y)"
Write-Host " "$csvs.Name"`n"
$outputfilename = "Final Registry Results"
Write-Host Creating: $outputfilename
$excelapp = New-Object -ComObject Excel.Application
$excelapp.SheetsInNewWorkbook = $csvs.Count
$xlsx = $excelapp.Workbooks.Add()
for ($i=1;$i -le $y;$i++) {
    $worksheet = $xlsx.Worksheets.Item($i)
    $worksheet.Name = $csvs[$i-1].Name
    $file = (Import-Csv $csvs[$i-1].FullName)
    $file | ConvertTo-Csv -Delimiter "`t" -NoTypeInformation | clip
    $worksheet.Cells.Item(1).PasteSpecial() | Out-Null
}

$output = "C:\Users\Francesco\Desktop\CSV\Results\Results.xlsx"
$xlsx.SaveAs($output)
$excelapp.Quit()

Проблема в том, что мне нужно запустить это на нескольких серверах, и серверы хорошо известны тем, что не имеет установленного Office , поэтому я не могу использовать Excel.Application.

Есть ли способ объединить несколько CSV в один CSV или XLSX без использования Excel.Application и сохранения каждого CSV на отдельном листе?

1 Ответ

0 голосов
/ 23 ноября 2018

@ AnsgarWiechers прав, ImportExcel мощный и не сложный в использовании. Однако для вашего конкретного случая вы можете использовать более ограниченный подход, используя OleDb (или ODBC или ADO) для записи в файл Excel, например, в базу данных. Вот пример кода, показывающий, как записать в файл Excel с помощью OleDb.

$provider = 'Microsoft.ACE.OLEDB.12.0'
$dataSource = 'C:\users\user\OleDb.xlsb'
$connStr = "Provider=$provider;Data Source=$dataSource;Extended Properties='Excel 12.0;HDR=YES'"
$objConn = [Data.OleDb.OleDbConnection]::new($connStr)
$objConn.Open()

$cmd = $objConn.CreateCommand()

$sheetName = 'Demo'
$cmd.CommandText = 'CREATE TABLE $sheetName (Name TEXT,Age NUMBER)'
$cmd.ExecuteNonQuery()

$cmd.CommandText = "INSERT INTO demo (Name,Age) VALUES ('Adam', 20)"
$cmd.ExecuteNonQuery()

$cmd.CommandText = "INSERT INTO demo (Name,Age) VALUES ('Bob',30)"
$cmd.ExecuteNonQuery()

$cmd.Dispose()
$objConn.Close()
$objConn.Dispose()

Вы не сказали много о файлах CSV, которые вы будете обрабатывать. Если данные столбца изменяются, для создания таблицы вам необходимо получить имена атрибутов (столбцов) из заголовка CSV (либо путем чтения первой строки файла CSV, либо путем перечисления свойств первого элемента, возвращаемого функцией Import- CSV).

Если ваши CSV-файлы содержат большое количество строк, запись по одной строке может быть медленной. В этом случае использование DataSet и OleDbDataAdapter может улучшить производительность (но я не проверял). Но в этот момент вы также можете использовать OleDb для чтения .csv непосредственно в DataSet, создать OleDbDataAdapter, установить свойство InsertCommand адаптера и, наконец, вызвать метод Update адаптеров. У меня нет времени писать и проверять все это.

Это не полное решение, просто демонстрация того, как использовать OleDb для записи в файл Excel.

Примечание: Я проверил это на сервере, на котором не было установлено Office или Excel. Поставщики данных Office, предварительно установленные на этом компьютере, были 32-разрядными, но я использовал 64-разрядную версию PowerShell. Чтобы получить 64-разрядные драйверы, я установил распространяемый Microsoft Access Database Engine 2016 , и это то, что я использовал для тестирования.

...