Automate exporting of Excel worksheets to PDF

0

Editor's note: The OP has abandoned this question and asked a variation at https://stackoverflow.com/questions/38766898/saving-excel-worksheets-to-pdf-using-powershell.

I have been trying to implement the following PowerShell script but without any luck. Can someone please help?

I know this script will save 1 PDF file per Excel workbook, however once I get this working I will look at exporting each Excel worksheet to separate PDF files.

ExportTo-ExcelPDF.ps1 from http://blogs.technet.com/b/heyscriptingguy/archive/2010/09/06/save-a-microsoft-excel-workbook-as-a-pdf-file-by-using-powershell.aspx

$path = "c:\fso" 
$xlFixedFormat = "Microsoft.Office.Interop.Excel.xlFixedFormatType" -as [type] 
$excelFiles = Get-ChildItem -Path $path -include *.xls, *.xlsx -recurse 
$objExcel = New-Object -ComObject excel.application 
$objExcel.visible = $false 
foreach($wb in $excelFiles) 
{ 
  $filepath = Join-Path -Path $path -ChildPath ($wb.BaseName + ".pdf") 
  $workbook = $objExcel.workbooks.open($wb.fullname, 3) 
  $workbook.Saved = $true 
  "saving $filepath" 
  $workbook.ExportAsFixedFormat($xlFixedFormat::xlTypePDF, $filepath) 
  $objExcel.Workbooks.close() 
} 
$objExcel.Quit()

Error messages:

The property 'Saved' cannot be found on this object. Verify that the
property exists and can be set.
At C:\ExportExcel.ps1:23 char:2
+  $workbook.Saved = $true
+  ~~~~~~~~~~~~~~~~~~~~~~~
  + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
  + FullyQualifiedErrorId : PropertyAssignmentException

saving C:\ExportExcel.pdf
Method invocation failed because [System.__ComObject] does not contain a
method named 'ExportAsFixedFormat'.
At C:\ExportExcel.ps1:25 char:2
+  $workbook.ExportAsFixedFormat($xlFixedFormat::xlTypePDF, $filepath)
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
  + FullyQualifiedErrorId : MethodNotFound

You cannot call a method on a null-valued expression.
At C:\ExportExcel.ps1:26 char:2
+  $objExcel.Workbooks.close()
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
  + FullyQualifiedErrorId : InvokeMethodOnNull

Exception calling "Quit" with "0" argument(s): "Call was rejected by callee.    
(Exception from HRESULT: 0x80010001 (RPC_E_CALL_REJECTED))"
At C:\ExportExcel.ps1:28 char:1
+ $objExcel.Quit()
+ ~~~~~~~~~~~~~~~~
  + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
  + FullyQualifiedErrorId : COMException
excel
powershell
asked on Stack Overflow Aug 4, 2016 by Ash • edited May 23, 2017 by Community

1 Answer

1

tl;dr

The most likely cause is that Excel's primary interop assembly isn't installed.


The error messages suggest that even though you managed the create the Excel-related objects per se, accessing their members (properties and methods) failed.

Sometimes, setting $VerbosePreference='Continue' helps; for instance, on my machine I see the following when I instantiate the Excel application object (New-Object -ComObject excel.application):

VERBOSE: The object written to the pipeline is an instance of the type "Microsoft.Office.Interop.Excel.ApplicationClass" from the component's primary interoperability assembly. If this type exposes different members than the IDispatch members, scripts that are written to work with this object might not work if the primary interoperability assembly is not installed.

Perhaps a missing interoperability assembly is your problem.

On my machine (PSv5, Excel 2010), this interoperability assembly is (a) not loaded by default, (b) is only loaded when you instantiate the Excel application object.

Thus, your code wouldn't work on my machine, because it references type [Microsoft.Office.Interop.Excel.xlFixedFormatType] - which is part of that interop assembly - before the Excel application object is created, which fails - silently, because the indirect type reference "Microsoft.Office.Interop.Excel.xlFixedFormatType" -as [type] simply returns $null - without complaining - if the type doesn't exist (yet).

If you instead use [Microsoft.Office.Interop.Excel.xlFixedFormatType] directly, you'll instantly get an error if the type doesn't exist / its assembly has not been loaded (yet).

In short:

  • Remove line $xlFixedFormat = "Microsoft.Office.Interop.Excel.xlFixedFormatType" -as [type].

  • In its stead, place $xlFixedFormat = [Microsoft.Office.Interop.Excel.xlFixedFormatType] after the objExcel = New-Object -ComObject excel.application line.

  • Debug your script and run $objExcel | Get-Member and $wb | Get-Member right after the first $objExcel.workbooks.open($wb.fullname, 3) call to see what members PowerShell can see.

    • If the $xlFixedFormat = [Microsoft.Office.Interop.Excel.xlFixedFormatType] line produces an error right away, or you don't see the members of interest (Saved, ExportAsFixedFormat, ...), the most likely cause is that the interop assembly isn't installed.
    • Another way to see if the interop assembly is loaded is to execute [Microsoft.Office.Interop.Excel.ApplicationClass] and see if type information is returned (as opposed to an error message).
answered on Stack Overflow Aug 4, 2016 by mklement0 • edited Aug 4, 2016 by mklement0

User contributions licensed under CC BY-SA 3.0