Войти

Показать полную графическую версию : [решено] Пакетное преобразование xls ->xlsx (xls -> csv)


Страниц : [1] 2

Ent0ma
07-07-2021, 08:19
Требуется скрипт для преобразования всех файлов в определенной папке xls в xlsx (или csv).

greg zakharov
07-07-2021, 09:41
Через COM Excel.Application: открыли документ, перевели в нужный формат, сохранили результат. А ежели в системе не развёрнут офисный пакет, на коленке пишется парсер ФС xls файла, конвертирующий данные таблиц в xml с последующей упаковкой в zip и сменой расширения на xlsx (в случае с csv можно использовать методы БД). И третий вариант - онлайн конверторы. curl'ом слать файлы на конвертацию, и если возвращается статус 200 (или любой иной удачный, согласно API), забрать результат также curl'ом.

Ent0ma
07-07-2021, 10:22
Через COM Excel.Application: открыли документ, перевели в нужный формат, сохранили результат. »
Офисный пакет установлен, проблема в том что там на месте пользователи не очень то дружат с компом/экселем. А файлов в папке много, которые требуется пересохранить - выгрузка из 1С сохраняет всегда в xls. Идеальный вариант: пользователь запускает скрипт или он отрабатывает автоматически конвертируя все файлы xls в папке в xlsx. VBA не хочу, сколько будет стоить скрипт на posh?

YuS_2
07-07-2021, 12:57
сколько будет стоить скрипт на posh? »
он будет бесценным (ну или пару кружек пива) :)
param (
$folderin = '.\TEST',
$folderout = '.\OUT',
$flt = '*.xls',
$ext = '.xlsx'
)

$fldin = gi $folderin
if (!(test-path $folderout)){md $folderout|out-null}
$fldout = gi $folderout
$excel = new-object -com "Excel.Application"
dir $fldin.fullname -filter $flt -file|%{
$workbook = $excel.workbooks.open($_.fullname)
$newname = $fldout.fullname + '\' + $_.basename + $ext
$workbook.saveas($newname, 51)
}
$excel.quit()

greg zakharov
07-07-2021, 13:54
YuS_2, дружище, ты забыл высвободить COM, только его экземпляр закрыл.

Elven
07-07-2021, 13:55
YuS_2, есть же beerware license (https://en.wikipedia.org/wiki/Beerware)

Вообще есть вот такой вариант (https://www.powershellgallery.com/packages/ImportExcel)
Сейчас нет возможности проверить, но скорей всего все это сделать можно будет в пару команд.

YuS_2
07-07-2021, 14:21
забыл высвободить COM, только его экземпляр закрыл. »
Да чего ему сделается? сессию закроют, объект попустит :)
Ну или добавить в конец скрипта, если принципиально:
[runtime.interopservices.marshal]::releasecomobject($excel)

есть же beerware license »
то шутка была... мне в реале хватает на пиво, чтобы за такие скрипты на пиво сшибать. Просто виртуального - можно похлебать... :)

Elven
07-07-2021, 14:56
YuS_2, beerware license не обязует пиво покупать, только намекает что автор кода не против этого.

megaloman
07-07-2021, 15:56
VBA не хочу » BoxIn = "Z:\Box_In"
BoxInOld = "_Old.xls"

Set Book = CreateObject("Excel.Application")
Book.Visible = False 'True ' False

With CreateObject("Scripting.FileSystemObject")
If Not .FolderExists(BoxIn + "\" + BoxInOld) Then Call .CreateFolder(BoxIn + "\" + BoxInOld)

For Each iFile In .GetFolder(BoxIn).Files
If LCase(Right(iFile, 4)) = ".xls" And Not .FileExists(iFile + "x") Then
With Book
.Workbooks.Open iFile
Call .ActiveWorkbook.SaveAs(iFile + "x", 51, , , , False)
.ActiveWorkbook.Close
End With
End If
.MoveFile iFile, BoxIn + "\" + BoxInOld + "\" + iFile.Name
Next
End With
Book.Quit

alpap
07-07-2021, 17:02
Вообще есть »
не хочет он с xls работать:
---
Exception: C:\...\PowerShell\Modules\ImportExcel\7.1.2\Public\Import-Excel.ps1:99
Line |
99 | … throw "Import-Excel does not support reading this extensi …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Import-Excel does not support reading this extension type .xls
---

DJ Mogarych
07-07-2021, 18:24
В составе Офиса есть конвертер.
excelcnv.exe -oice file.xls file.xlsx

Iska
07-07-2021, 19:43
YuS_2, здесь:
https://i.imgur.com/LNAFwBv.png
надо быть аккуратнее и не забывать про короткие имена файлов. Посему в данном случае можно перебирать все и обязательно внутри ещё и проверять условие на точное соответствие расширения.

В составе Офиса »
DJ Mogarych, он точно в составе Office, а не отдельного Microsoft Office Compatibility Pack for Word, Excel, and PowerPoint File Formats?
Вопрос снимается. Для старого Office — это точно отдельный конвертер, а в составе новых, надо полагать, идёт в комплекте.

Оставлю сие здесь себе для памяти:

excelcnv command line: Hexacorn | Blog Excellent Conversions (and downloads) (https://www.hexacorn.com/blog/2021/05/23/excellent-conversions-and-downloads/)

И всё ещё не нашёл ответа про параметр «-nme».

YuS_2
07-07-2021, 20:34
надо быть аккуратнее и не забывать про короткие имена файлов. »
надо отключать пережитки прошлого... напрочь... в том числе и ISE... тогда напрягать ресурсы памяти не надо будет. :)
fsutil 8dot3name set 1

greg zakharov
07-07-2021, 22:30
Да чего ему сделается? сессию закроют, объект попуститПрежде - никто не знает, когда сессия завершится, да и по завершении невысвобожденный COM гарантировать ничего не может. В итоге получим либо утечку ресурсов, либо зомбика, либо... Вариантов много.

alpap
07-07-2021, 23:03
никто не знает, когда сессия завершится »
я, если и закрываю сессию, то у меня все равно EXCEL висит в процессах, $Excel.Quit() не помогает, приходится еще такую строчку писать:
Stop-Process -Name EXCEL
а вот WINWORD не висит, закрывается по $Word.Quit(), хотя для надежности все равно пишу и Stop-Process -Name WINWORD

greg zakharov
07-07-2021, 23:18
alpap, ReleaseComObject по идее должно быть достаточно.

alpap
07-07-2021, 23:53
нет, попробовал
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($Excel)
недостаточно, вернулся на spps -n Excel

Iska
08-07-2021, 00:13
fsutil 8dot3name set 1 »
У себя-то отключить можно… А если — не у себя?! Так что, пока — помним ;).

greg zakharov
08-07-2021, 00:15
alpap, речь не о завершении связанного процесса, а об уменьшении количества ссылок на указанный COM. Сигнал к завершению процессу подаётся, если количество ссылок равно нулю (значение возвращаемое ReleaseComObject). А вот если по истечении кванта времени, отведённого на завершение, процесс продолжает "болтаться", ничего не остаётся, как прибивать его вручную.

YuS_2
08-07-2021, 08:17
ReleaseComObject по идее должно быть достаточно. »
Тоже так думал... но как показала практика, микрософт (как и я в данном случае :) ), плевать хотел на висяки в памяти и освобождение ресурсов, предназначенным для этого способом, работает как того захочется "великому электронобайту" от микрософт... может сработать, а может и не сработать. :)
Придется таки следить за наличием процесса в памяти (желательно по PID, чтобы не убить лишнего) и убивать его по завершении скрипта... или попробовать найти более вменяемый способ (мне лень этим заниматься, пока)...

А вот если по истечении кванта времени, отведённого на завершение, процесс продолжает "болтаться", ничего не остаётся, как прибивать его вручную. »
Вот-вот. Но задержки ставил, так что пока корректного способа не обнаружил...




© OSzone.net 2001-2012