Reputation: 334
I have a Delphi routine which runs through a list of Excel files, opens them with MS Excel, iterates through the sheets setting the PageSetup
for each sheet so all columns will fit on one page and then export all sheets to a single PDF.
MSApp := CreateOLEObject('Excel.Application');
doc := MSApp.WorkBooks.Open(fileOpenDialog1.FileName, False, True, EmptyParam, '', '',
True, EmptyParam, EmptyParam, EmptyParam, False, EmptyParam, False, False, EmptyParam);
MSApp.PrintCommunication := False;
doc.Sheets.Item[1].PageSetup.FitToPagesWide := 1;
if doc.Sheets.Count > 1 then
begin
doc.Sheets.Item[1].Select(True);
for i := 2 to doc.Sheets.Count do
begin
doc.Sheets.Item[i].Select(False);
doc.Sheets.Item[i].PageSetup.FitToPagesWide := 1;
end;
end;
doc.ExportAsFixedFormat(xlTypePDF, outPutFile, EmptyParam, False,
EmptyParam, EmptyParam, EmptyParam, False, EmptyParam);
MSApp.PrintCommunication := True;
If there is only one sheet setting FitToPagesWide
to 1 page works as expected. However, if there is more than one page and say the first page is too wide, the changes to the PageSetup
for the first page do not stick and are lost by the time the file is exported.
Looking at the various examples online and the MS docs, I have been unable to find anything to suggest that the above should not work as expected or that there is some property that needs to be set in order to make PageSetup
changes stick before moving on to the next sheet.
I could save each sheet to PDF individually and then merge the PDFs, but it seems to me that shouldn't be necessary.
Upvotes: 2
Views: 1133
Reputation: 3830
The issue you observe is caused improper use of Application.PrintCommunication
property. All changes to PageSetup
are cached from the moment when you set it to False
until those changes are commited by setting the property value back to True
. But you do that after exporting the workbook via ExportAsFixedFormat
. The solution is simple:
PrintCommunication
True
before the exportNow why the first worksheet is exported in the layout as you expected? I can only guess that it's because it was already saved with width shrinking configured on the first worksheet only:
Here are some further observations:
PageSetup
.FitToPagesTall
to 0
(or False
) in case the worksheet has configured height shrinking.Of course the recommended way to perform multiple changes to PageSetup
is within PrintCommunication := False
block. With the above applied you get:
procedure ExportWorkbookAsPDF(const InputFileName, OutputFileName: string);
var
App, Workbook, PageSetup: OleVariant;
Index: Integer;
begin
App := CreateOleObject('Excel.Application');
try
App.DisplayAlerts := False;
App.Interactive := False;
Workbook := App.Workbooks.Open(FileName := InputFileName, UpdateLinks := False,
ReadOnly := True, IgnoreReadOnlyRecommended := True);
try
App.PrintCommunication := False;
for Index := 1 to Workbook.Sheets.Count do
begin
PageSetup := Workbook.Sheets.Item[Index].PageSetup;
PageSetup.FitToPagesWide := 1;
PageSetup.FitToPagesTall := 0;
end;
App.PrintCommunication := True;
Workbook.ExportAsFixedFormat(xlTypePDF, OutputFileName);
finally
Workbook.Close(False);
end;
finally
App.Quit;
end;
end;
In your original code you use Workbook.Sheets
collection to iterate over all sheets in a workbook, which includes also charts. To apply PageSetup
to worksheets only use Workbook.Worksheets
collection. See Worksheets vs Sheets for more information.
Upvotes: 2