2011-06-22 13 views
11

Mam klienta, który musi przekonwertować pliki XLS na XLSB. Czy ktoś zrobił to programowo (z dodatkiem lub bez - nie ma znaczenia - po prostu trzeba go zautomatyzować)? Szukam sposobu na zautomatyzowanie tego.Konwersja XLS do XLSB programowo?

Na marginesie, klient pyta o to, ponieważ używają Sharepoint i wydaje się, że ma sposób na analizę plików XLSB szybciej i łatwiej niż XLS ??? Pracuję nad ulepszeniem mojej wiedzy o SharePoint, ale w międzyczasie staram się znaleźć odpowiedź na ten problem XLSB.

Dzięki.

+0

To dość proste, jeśli można użyć wczesnego wiązania Office Interop. Określ dodatkowe ograniczenia. Czy możesz zapisywać i operować na plikach na dysku lokalnym? –

+0

@Petr - Tak, mogę zapisywać i operować na plikach na dysku lokalnym. –

Odpowiedz

14

Cóż, to nie jest krótki Format Verison:

using Microsoft.Office.Interop.Excel; 

// init excel 
Application excelApplication = new Application(); 

// ... 

// open book in any format 
Workbook workbook = excelApplication.Workbooks.Open("1.xls", XlUpdateLinks.xlUpdateLinksNever, true, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); 

// save in XlFileFormat.xlExcel12 format which is XLSB 
workbook.SaveAs("1.xlsb", XlFileFormat.xlExcel12, Type.Missing, Type.Missing, Type.Missing, Type.Missing, XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); 

// close workbook 
workbook.Close(false, Type.Missing, Type.Missing); 

// ... 

// shutdown excel 
excelApplication.Quit(); 

Będziesz potrzebował instalację programu Excel z obsługą programowania .NET (wyłączone domyślnie instalator!) I odniesienia montażu MS Office PIA dla programu Excel z listy projekt:

add Excel PIA reference

Referencje: Workbooks.Open, workbook.SaveAs, XlFileFormat.xlExcel12

0

This może być używany z wiersza poleceń.

+0

Wygląda na to, że obsługuje tylko konwersję ** z ** (nie do) .xlsb :(co mnie zaskakuje, ponieważ wydaje się używać Excela COM Interop dla .xlsb, co powinno spowodować, że zapisanie go będzie równie łatwe jak załadowanie go. –

3

Piszę ten kod uprawnień, aby konwertować wiele plików * .xls w wielu folderach rekursywnie. skrypt ten powinien wybrać folder, przekonwertować wszystkie pliki i usunąć oryginał (przenieść do kosza) wyświetlać każdą nazwę pliku w konsoli PowerShell.

<# 
    .SYNOPSIS 
    Covert all *.xls files recursivly in a provided path 
    .DESCRIPTION 
    XLS files within a provided path are recursively enumerated and convert to XLSB files (with macro). 
    The original XLS files are deleted if newfile has created (in trash), a new XLSb file replace the old file. 
    #> 
    $autor='alban Lopez' 
    $version=0.85 
    $email='[email protected]' 

    function ConvertTo-XLSB { 
    <# 
    .SYNOPSIS 
    XLS files within a provided path are recursively enumerated and convert to XLSB files. 
    .DESCRIPTION 
    XLS files within a provided path are recursively enumerated and convert to XLSB files. 
    The original XLS files remain intact, a new XLSB file will be created. 
    .PARAMETER Path 
    This parameter takes the input of the path where the XLS files are located. 
    .PARAMETER Visible 
    Using the parameter will show you how Excel does the work. Not using the parameter will enable Excel 
    to accomplish its tasks in the background. 
    Note: Bu not using this parameter you will be able to convert some XLS files which have corruptions 
    in them, when using the parameter and therefor the Excel GUI will give you an error. 
    .PARAMETER ToFolder 
    This parameter enables you to provide a location where the file is saved. When this parameter is 
    not used, the file will be saved as an XLS file in the same location as where the 
    original XLS file is located. 
    .EXAMPLE 
    ConvertTo-XLSB -Path 'D:\Data\2012' 
    .EXAMPLE 
    ConvertTo-XLSB -Path 'D:\Data\2012' -Visible 
    .EXAMPLE 
    ConvertTo-XLSB -Path 'D:\Data\2012' -ToFolder 'D:\Data\2012XLSB' 
    .EXAMPLE 
    ConvertTo-XLSB -Path 'D:\Data\2012' -Visible -ToFolder 'D:\Data\2012XLSB' 
#> 
    [cmdletbinding()] 

     param (
      [parameter(mandatory=$true)][string]$Path, 
      [parameter(mandatory=$false)][switch]$Visible, 
      [parameter(mandatory=$false)][string]$ToFolder 
     ) 
     begin { 
      $Excel = New-Object -ComObject excel.application 
      $Excel.DisplayAlerts = $false 
      # $xlFixedFormat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlWorkbookDefault # xlsx 
      $xlFixedFormat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlExcel12 # 50 = xlsb 
      $shell = new-object -comobject "Shell.Application" 

      $count = 0 
      $count_OK = 0 
      $count_Nok = 0 

      if ($Visible -eq $true) { 
       $Excel.visible = $true 
      } else { 
       $Excel.visible = $false 
      } 
      $filetype = "*xls" 
     } process { 
      if (Test-Path -Path $Path) { 
       Get-ChildItem -Path $Path -Include '*.xls' -recurse | ForEach-Object { 
        if ($ToFolder -ne '') { 
         $FilePath = Join-Path $ToFolder $_.BaseName 
        } else { 
         $FilePath = ($_.fullname).substring(0, ($_.FullName).lastindexOf(".")) 
        } 
        $FilePath += ".xlsb" 
        $WorkBook = $Excel.workbooks.open($_.fullname) 
        $WorkBook.saveas($FilePath, $xlFixedFormat) 
        $WorkBook.close() 
        $OldFolder = $Path.substring(0, $Path.lastIndexOf("\")) + "\old" 
        if (test-path $FilePath){ 
         $count_OK++ 
         Write-Host -nonewline "$count_OK > " 
         Write-Host $_.fullname -ForegroundColor Cyan 
         $item = $shell.Namespace(0).ParseName("$($_.fullname)") 
         $item.InvokeVerb("delete") 
        } else { 
         $count_Nok++ 
         Write-Host -nonewline "$count_Nok > " 
         Write-Host $_.fullname -ForegroundColor red 
        } 
        $count++ 
       } 
      } else { 
       return 'No path provided or access has been denied.' 
      } 
     } end { 
      Write-Host '========================================================' -ForegroundColor yellow 
      Write-Host -nonewline "Total : $count"; 
      Write-Host -nonewline "/Erreurs : $count_Nok/" -ForegroundColor red; 
      Write-Host "convertis : $count_ok" -ForegroundColor green; 
      Write-Host '========================================================' -ForegroundColor yellow 

      $Excel.Quit() 
      $Excel = $null 
      [gc]::collect() 
      [gc]::WaitForPendingFinalizers() 
     } 
    } 


#============================================================================= 
# Displays a select file dialog box, returning the path to a CSV file. 
#============================================================================= 
function Read-FolderBrowserDialog([string]$Message, [string]$InitialDirectory) 
{ 
    $app = New-Object -ComObject Shell.Application 
    $folder = $app.BrowseForFolder(0, $Message, 0, $InitialDirectory) 
    if ($folder) { return $folder.Self.Path } else { return $false } 
} 

'' 
'Choisir le dossier source >' 
$source = Read-FolderBrowserDialog -Message "Dossier source" 

while ($source) 
{ 
    "Convertion de tous les fichiers du dossier : $source" 
    $ConvTime = Measure-Command {ConvertTo-XLSB -Path $source} 
    Write-Host "$($ConvTime.Hours):$($ConvTime.Minutes):$($ConvTime.Seconds)"; 
    '' 
    "End" 
    '' 
    'Choisir le dossier source >' 
    $source = Read-FolderBrowserDialog -message "Dossier source" -InitialDirectory $source 
    #$dest = Select-FolderDialog -message "Dossier Destination (sera conservé)" -RootFolder $source 
} 
start-sleep -s 30 
+0

Czy istnieje możliwy przepływ w skrypcie, ponieważ podczas próby uruchomienia bez okna dialogowego wyboru folderu (umieszczam te linie pod komentarzem) - po prostu nie wykona konwersji.Zaprojektuję go z "cmd" systemu Windows ... Używam dokładnie poleceń pokazanych w sekcji PRZYKŁADY ... Czy to możliwe, że "-ExecutionPolicy Bypass", które dostarczam jako parametr powershell.exe, w jakiś sposób przeszkadza? – WD11

+0

Ya dzięki !! dla tego kodu działa –

Powiązane problemy