Excel nach PDF konvertieren?

  • Hallo liebe Community,

    Ich hab ein kleines Problem bei meinem Autoit Script.
    Eine kleine GUI ermöglicht es dem Benutzer, Daten einzugeben, die anschließen in eine Excel-Tabelle geschrieben werden.

    Das einzige Problem ist jetzt, die Tabelle als PDF oder XPS-Dokument abzuspeichern.
    Ist das überhaupt möglich? Wenn ja, wie wäre der Befehl dafür?

    _ExcelBookSaveAs geht leider nicht, da hier nur wenig Formate unterstützt werden.

    Bin für jeden sinvollen Beitrag dankbar!

    MathyourMath

  • Ich denke zwar das es über das Excel-COM-Objekt auch möglich sein wird aber ganz spontan hätte ich folgendes vorzuschlagen:

    • PDF-Drucker installieren (wie FreePDF) und als Standarddrucker einrichten
    • Datei Per Shellexecute() (und "print" statt "open") die Datei drucken.
  • Hängt von der installierten Excel Version ab. Was setzt Du ein?

  • Meine Excel UDF (den Download-Link findest Du in meiner Signatur) hat bereits eine Funktion dafür: _Excel_Export

  • Mit dem ExcelEX UDF ist das speichern als pdf auch direkt möglich.

    Hier die modifizierte Funktion aus dem ExcelEX UDF:

    Spoiler anzeigen
    [autoit]


    ;===============================================================================
    ; Function Name: _ExcelSaveAsEX($oExcel, $Fileformat, $NewFilepath, $Close = True)
    ; Description: Speichert eine Exceldatei in einem bestimmten Format ab
    ; Parameter(s): $oExcel Ein Excelobject, wie es von _ExcelbookOpen oder _ExcelbookNew zurückgegeben wird
    ; $Fileformat Der Dateityp, in dem gespeichert werden soll (xlsx, xlsb, xlsm, xls, csv, txt, prn)
    ; $NewFilepath Speicherort und Dateiname der neuen Datei
    ; $Close = True Soll nach dem Speichern das Objekt geschlossen werden? (Standard = True)
    ; Return Value(s): Erfolg Gibt 1 zurück
    ; Fehler @error 1 - $oExcel ist kein Objekt
    ; 2 - $Fileformat ist keine bekannte Dateiendung oder Formatnummer
    ; Author(s): TheLuBu ([email='LuBu@veytal.com'][/email])
    ; Copyright: TheLuBu ([email='LuBu@veytal.com'][/email])
    ;===============================================================================
    Func _ExcelSaveAsEX($oExcel, $Fileformat, $NewFilepath, $Close = True)
    If Not IsObj($oExcel) Then Return SetError(1, 0, 0)
    Switch $Fileformat
    Case 51, "xlsx", ".xlsx"
    $Fileformat = 51
    Case 50, "xlsb", ".xlsb"
    $Fileformat = 50
    Case 52, "xlsm", ".xlsm"
    $Fileformat = 52
    Case 6, "csv", ".csv"
    $Fileformat = 6
    Case -4158, "txt", ".txt"
    $Fileformat = -4158
    Case 36, "prn", ".prn"
    $Fileformat = 36
    Case 56, "xls", ".xls"
    $Fileformat = 56
    Case 57, "pdf", ".pdf" ; hinzugefügt
    $Fileformat = 57 ; hinzugefügt
    Case Else
    Return SetError(2, 0, 0)
    EndSwitch
    With $oExcel
    .Application.DisplayAlerts = False ; Schaltet Fehlermeldungen bei Excel aus
    .ActiveWorkBook.SaveAs($NewFilepath, $Fileformat)
    If $Close Then
    .ActiveWorkbook.Close ; Schließt die Tabelle
    .Quit ; Schließt das Workbook
    EndIf
    EndWith
    Return 1
    EndFunc ;==>_ExcelSaveAsEX

    [/autoit] [autoit][/autoit] [autoit][/autoit]


    Hier noch ein Beispiel auf Basis der Hilfedatei:

    Spoiler anzeigen
    [autoit]


    #include <Excel.au3>
    #include <excelex.au3>

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Local $sFilePath1 = @ScriptDir & "\Test1.xlsx" ; Diese Datei sollte bereits existieren
    Local $oExcel = _ExcelBookOpen($sFilePath1)

    [/autoit] [autoit][/autoit] [autoit]

    ; Fehler, die während des Öffnens der Datei auftreten, anzeigen
    If @error = 1 Then
    MsgBox(0, "Fehler!", "Das Excel-Objekt konnte nicht erstellt werden.")
    Exit
    ElseIf @error = 2 Then
    MsgBox(0, "Fehler!", "Die Datei existiert nicht.")
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $NewFilepath = @scriptdir&"\TestsaveExcel"
    $fileformat = 57

    [/autoit] [autoit][/autoit] [autoit]

    With $oExcel
    .Application.DisplayAlerts = False ; Schaltet Fehlermeldungen bei Excel aus
    .ActiveWorkBook.SaveAs($NewFilepath, $Fileformat)
    EndWith

    [/autoit] [autoit][/autoit] [autoit]

    msgbox(0,"gespeichert",$i,1)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit]

    Die Variable $fileformat erzeugt folgende Dateitypen aus Excel:

    1 = xls
    2 = slk
    3 = txt
    6 = csv
    17 = xlt
    50 = xlsb
    51 = xlsx
    52 = xlsm
    53 = xltx
    55 = xlam
    57 = pdf
    58 = XPs
    60 = ods

    2 Mal editiert, zuletzt von qwert23 (31. Januar 2014 um 09:04)

  • Hallo zusammen!

    Mich interessiert das Thema auch. Leider bekomme ich es nicht ans laufen.
    Hab das genannte Beispiel mal getestet.
    Variable $i ist auch nicht deklariert.
    Das Script öffnet zwar die test1.xlsx und gibt gespeichert in der MsgBox aus, aber eine PDF finde ich nicht.

    Gruß
    Sirius

  • Die Zeile 17 war nicht korrekt. Habe nicht gesehen, dass mit c&p der "\" nicht korrekt übergeben wurde. $i wird in diesem Beispiel nicht benötigt und ist entfernt. Sorry!

  • Hi gwert23!

    Vielen Dank, funzt! :) Kann man dem Script auch sagen, dass es nicht nur die Tabelle 1 sonder, wenn was in Tabelle 2 und 3 was steht, dass er das auch in ein PDF umwandelt?
    So wie gesamte Arbeitsmappe drucken.

    Gruß
    Sirius

  • Mit

    _ExcelSheetActivate($oExcel, "hier das Arbeitsblatt angeben")

    das Arbeitsblatt aktivieren und erneut speichern. Bitte jeweils die Zieldatei neu bestimmen.

    Einmal editiert, zuletzt von qwert23 (31. Januar 2014 um 10:24)

  • Das weiß ich aktuell nicht...
    Als Lösungsvorschlag, wenn Acrobat Writer installiert ist, würde ich anschließend die gewünschten pdf Dateien neu zusammenstellen.
    Dazu gibt es im engl. Forum Beispiel, wie dieses:

    Spoiler anzeigen
    [autoit]


    Dim $filelist[1]

    [/autoit] [autoit][/autoit] [autoit]

    global $sourcepath

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; example merging files
    $t = ObjCreate("acrobat.pdf")

    [/autoit] [autoit][/autoit] [autoit]

    $var= FileSelectFolder("Select folder", "","",$sourcepath) & ""
    MergeFiles($var,FileSaveDialog( "Select Filename", $var, "PDF Files (*.pdf)", 3))
    ; example end

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    func GetRotation($Targetpath)
    ;----------------------------------------------------
    ; Get the Rotation of a Page (eg. page 1)
    ; Ex.: msgbox(0,"Rotation",GetRotation("c:\pdft\test.pdf" ))
    ;----------------------------------------------------

    if not FileExists($Targetpath) then
    return -1
    endif

    $SourcePDF = ObjCreate("AcroExch.PDDoc")

    if not IsObj($SourcePDF) then
    return -2
    endif

    $b = $SourcePDF.Open($Targetpath)
    $rotation = $sourcePDF.AcquirePage(0).GetRotate
    $SourcePDF.close
    $sourcePDF=""
    return $rotation ; in Degree
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    func MergeFiles($SourcePath , $DestinationPath)

    [/autoit] [autoit][/autoit] [autoit]

    if fileexists($DestinationPath) then
    FileDelete($DestinationPath)
    endif

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    getfiles($sourcepath, "*.pdf") ; Search Files in Dir
    if $filelist[0] < 2 then
    Msgbox(32,"Info", "Ther are less than two files in folder")
    exit
    endif

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    for $n=2 to $filelist[0]
    ;msgbox(0,"Info" , $filelist[0] & " " & $filelist[$n])
    ProgressOn("PDF Merge","Processing ...")
    ProgressSet((($n-1)/$filelist[0]) * 100, $filelist[$n-1])

    if $n=2 then
    pdfmerge($sourcepath & $filelist[$n-1],$sourcepath & $filelist[$n], $DestinationPath)
    else
    pdfmerge($DestinationPath, $sourcepath & $filelist[$n], $DestinationPath)
    endif
    next
    ProgressSet(100, $filelist[$filelist[0]])
    sleep(800)
    ProgressOff()
    Endfunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    func getfiles($dir, $filter) ; search files in dir
    Global $filelist[1]

    [/autoit] [autoit][/autoit] [autoit]

    $n=0
    $search= FileFindFirstFile($dir & $filter)
    ; Check if the search was successful
    If $search = -1 Then
    MsgBox(0, "Error", "No files/directories matched the search pattern")
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $n=$n+1
    $file = FileFindNextFile($search)
    If @error Then ExitLoop
    redim $filelist[$n+1]
    $filelist[$n]= $file
    $filelist [0] = $n
    WEnd
    ; Close the search handle
    FileClose($search)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    func PDFMerge($File1, $File2, $Fileout)
    ; ---------------------------------------
    ; File1 first file
    ; File2 second file (inserted after)
    ; Fileout is the saving name
    ;
    ; returns 1 on success
    ; returns -1 Error insert Pages
    ; returns -2 Error Object Create
    ;----------------------------------------

    $SourcePDF = ObjCreate("AcroExch.PDDoc")
    if not IsObj($SourcePDF) then
    return -2
    endif

    $b = $SourcePDF.Open($file1)

    [/autoit] [autoit][/autoit] [autoit]

    $TargetPDF = ObjCreate("AcroExch.PDDoc")
    $b = $TargetPDF.Open($file2)

    [/autoit] [autoit][/autoit] [autoit]

    $intSourcePgs = $SourcePDF.GetNumPages
    $intInsertPgs = $TargetPDF.GetNumPages
    if not $SourcePDF.InsertPages($intSourcePgs-1, $TargetPDF, 0, $intInsertPgs, False) = -1 then
    $SourcePDF.Close
    $TargetPDF.Close
    $SourcePDF=""
    $TargetPDF=""
    return -1
    endif
    $b = $SourcePDF.Save(1, $fileout)
    $SourcePDF.Close
    $TargetPDF.Close
    $SourcePDF=""
    $TargetPDF=""
    return 1
    endfunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    func GetPagesCount($target); count pages
    $AcroPDDoc = ObjCreate("AcroExch.PDDoc")
    if @error then return -1
    $bPDF = $AcroPDDoc.Open($target)
    if @error then return -2
    $Pages= $AcroPDDoc.GetNumPages
    $bPDF = $AcroPDDoc.Close
    return $pages
    endfunc

    [/autoit]

    Sicherlich bist Du damit flexibler und kannst die Arbeitsblätter individuell zusammenstellen.
    Das Script läßt sich dazu schnell anpassen, damit alles im Hintergrund erfolgt.
    Kommt das Deinen Vorstellungen nahe?

  • Also besteht nicht die Möglichkeit alle Arbeitsmappen in denen etwas geschrieben ist gleichzeitig in eine PDF zu konvertieren?

    Doch, geht.
    Alle gewünschten Arbeitsblätter in einem Range zusammenfassen (Methode Union) und diesen dann mit Methode ExportAsFixedFormat als PDF rausschreiben.

  • Hallo zusammen.

    Ich muss das Thema nochmal anschreiben! :) Ich hab mir jetzt mal was gebastelt. Leider komme ich jetzt nicht mehr weiter. Hier erstmal mein Script (Achtung ich bin Anfänger!:(

    Spoiler anzeigen


    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <ProgressConstants.au3>
    #include <WindowsConstants.au3>
    #include <Excel.au3>
    #include <excelex.au3>
    #Region ### START Koda GUI section ### Form=c:\users\schirmer\desktop\exceldoku2pdf.kxf
    $exceldoku2pdf = GUICreate("exceldoku2pdf", 615, 438, 191, 124)
    $Convert = GUICtrlCreateButton("Convert", 112, 264, 113, 49)
    $Exit = GUICtrlCreateButton("Exit", 384, 264, 115, 49)
    $Progress1 = GUICtrlCreateProgress(160, 344, 313, 33)
    $Oeffnen = GUICtrlCreateButton("Öffnen", 264, 144, 73, 49)
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###


    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Exit
    beenden()

    Case $oeffnen
    oeffnen()

    Case $Convert
    convert()

    EndSwitch
    WEnd

    Func oeffnen()
    Global $code = FileOpenDialog("Wähle XLSX oder XLS Datei aus!",@StartupDir, "(*.xlsx;*.xls)",1 + 4)

    EndFunc

    Func convert()

    Local $oExcel = _ExcelBookOpen($code)
    Local $vSheet = 1

    If @error = 1 Then
    MsgBox(0, "Fehler!", "Das Excel-Objekt konnte nicht erstellt werden.")
    Exit
    ElseIf @error = 2 Then
    MsgBox(0, "Fehler!", "Die Datei existiert nicht.")
    Exit
    EndIf
    _ExcelSheetActivate($oExcel, $vSheet)
    $NewFilepath = $code
    $fileformat = 57

    With $oExcel
    .Application.DisplayAlerts = False
    .ActiveWorkBook.SaveAs($NewFilepath, $Fileformat)
    EndWith

    msgbox(0,"Done","Die Datei wurde in PDF convertiert")
    Sleep(50)
    _ExcelBookClose($oExcel, 1)
    Sleep(50)
    ProcessClose("excel.exe")
    Local $PID = ProcessExists("excel.exe")
    If $PID Then ProcessClose($PID)

    EndFunc

    Func beenden()
    Exit
    EndFunc

    Ich möchte, dass man mehrere XLSX oderXLS Dateien aufwählen kann. Sobald ich aber mehr als eine Datei auswähle, sagt das Script, dass die Datei nicht vorhanden ist.
    Wie bekomme ich das hin, damit ich mehrere Dateien nacheinander in PDF Konvertieren kann?

    Vielen Dank!

    Einmal editiert, zuletzt von Sirius (8. Februar 2014 um 12:11)

  • Hi,
    schau dir mal in deiner Funktion oeffnen() an, was nach der Dateiauswahl von mehreren Dateien in der Variable $code steht...

  • So, ich hab mir jetzt mal _FileListToArray. Ich denke, dass ich damit die variable $code auseinander nehmen muss, und das diese Informationen in Arrays geschrieben werden. Richtig?