#powershell
#powershell
Вопрос:
Я пытаюсь вывести запрос из базы данных в xlsx, но на это уходит так много времени, потому что требуется обработать около 20 000 записей, есть ли более простой способ сделать это?
Я знаю, что есть способ сделать это для csv, но я пытаюсь избежать этого, потому что, если в записях будет какая-либо запятая, она будет принята за другой столбец, и это испортит информацию
это мой код
$xlsObj = New-Object -ComObject Excel.Application
$xlsObj.DisplayAlerts = $false
$xlsWb = $xlsobj.Workbooks.Add(1)
$xlsObj.Visible = 0 #(visible = 1 / 0 no visible)
$xlsSh = $xlsWb.Worksheets.Add([System.Reflection.Missing]::Value, $xlsWb.Worksheets.Item($xlsWb.Worksheets.Count))
$xlsSh.Name = "QueryResults"
$DataSetTable= $ds.Tables[0]
Write-Output "DATA SET TABLE" $DataSetTable
[Array] $getColumnNames = $DataSetTable.Columns | SELECT *
Write-Output "COLUMN NAMES" $DataSetTable.Rows[0]
[Int] $RowHeader = 1
foreach ($ColH in $getColumnNames)
{
$xlsSh.Cells.item(1, $RowHeader).font.bold = $true
$xlsSh.Cells.item(1, $RowHeader) = $ColH.ColumnName
Write-Output "Nombre de Columna"$ColH.ColumnName
$RowHeader
}
[Int] $rowData = 2
[Int] $colData = 1
foreach ($rec in $DataSetTable.Rows)
{
foreach ($Coln in $getColumnNames)
{
$xlsSh.Cells.NumberFormat = "@"
$xlsSh.Cells.Item($rowData, $colData) = $rec.$($Coln.ColumnName).ToString()
$ColData
}
$rowData ; $ColData = 1
}
$xlsRng = $xlsSH.usedRange
[void] $xlsRng.EntireColumn.AutoFit()
#Se elimina la pestaña Sheet1/Hoja1.
$xlsWb.Sheets(1).Delete() #Versión 02
$xlsFile = "directory of the file"
[void] $xlsObj.ActiveWorkbook.SaveAs($xlsFile)
$xlsObj.Quit()
Start-Sleep -Milliseconds 700
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsRng)) {''}
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsSh)) {''}
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsWb)) {''}
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsObj)) {''}
[gc]::collect() | Out-Null
[gc]::WaitForPendingFinalizers() | Out-Null
$oraConn.Close()
Комментарии:
1. Что означает «если в записях была какая-либо запятая, она будет принята за другой столбец, и это испортит информацию»?
2. Файлы @Bill_Stewart .csv обычно хранятся в виде списков, разделенных запятыми. итак, если в его данных есть запятая, файл обработает их как конец столбца.
3. Это звучит как воображаемая проблема. Смотрите Вывод из
[pscustomobject]@{Column1 = "string,with,commas,"; Column2 = 123}|ConvertTo-Csv -NoTypeInformation
например, PowerShell определяет границы значений с помощью кавычек. CSV как формат, очевидно, определен свободно, но большинство анализаторов CSV, с которыми я сталкивался, учитывают строки, заключенные в кавычки.4. @HeberSolis Это не зависит от того, как был определен входной объект, он будет заключать в кавычки любую строку
5. Проверьте, какой символ вы получаете с
(Get-Culture).TextInfo.ListSeparator
. Если это НЕ запятая, в Excel возникают проблемы с ее чтением, и вам следует использоватьConvertTo-Csv
orExport-Csv
вместе с любым параметром-Delimiter '<theListSeparatorCharacter>'
ИЛИ (что намного проще) добавить переключатель-UseCulture
. Затем, при двойном щелчке CSV-файла, Excel считывает его просто отлично.
Ответ №1:
Я пытаюсь избегать [CSV-файлов], потому что, если в записях была какая-либо запятая, она будет принята за другой столбец, и это испортит информацию
Это произойдет только в том случае, если вы попытаетесь сконструировать формат вывода вручную. Встроенные команды типа Export-Csv
и ConvertTo-Json
автоматически заключат значения в кавычки по мере необходимости:
PS C:> $customObject = [pscustomobject]@{ID = 1; Name = "Solis, Heber"}
PS C:> $customObject
ID Name
-- ----
1 Solis, Heber
PS C:> $customObject |ConvertTo-Csv -NoTypeInformation
"ID","Name"
"1","Solis, Heber"
Обратите внимание, в приведенном выше примере, как:
- Строковое значение, присвоенное
$customObject.Name
, не содержит никаких кавычек, но - В выводе из
ConvertTo-Csv
мы видим значения и заголовки, четко заключенные в кавычки
PowerShell автоматически перечисляет данные строки при передаче [DataTable]
экземпляра, поэтому создание CSV может (в зависимости от содержимого) быть таким простым, как:
$ds.Tables[0] |Export-Csv table_out.csv -NoTypeInformation
Что, если вам нужны значения, разделенные табуляцией (или любым другим разделителем без запятой)?
*-Csv
Команды поставляются с -Delimiter
параметром, в который можно передать пользовательский разделитель:
# This produces semicolon-separated values
$data |Export-Csv -Path output.csv -Delimiter ';'
Обычно я стараюсь воздерживаться от рекомендаций библиотек конкретных модулей, но если вы настаиваете на записи в XSLX, я бы посоветовал проверить ImportExcel (пусть название не вводит вас в заблуждение, оно выполняет больше, чем импорт из Excel, включая экспорт и форматирование данных из PowerShell -> XSLX)
Комментарии:
1. Кроме того, вы всегда можете использовать
-Delimiter
для использования чего-либо другого, кроме,