Excel PageSetup 多张纸
Excel PageSetup multiple sheets
我有一个 Delphi 例程,它运行 Excel 文件列表,用 MS Excel 打开它们,遍历 sheets 设置 PageSetup
对应每个 sheet,因此所有列都将适合一页,然后将所有 sheet 导出到单个 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;
如果只有一个 sheet 设置 FitToPagesWide
为 1 页,则按预期工作。但是,如果有多个页面并且说第一页太宽,对第一页的 PageSetup
的更改不会保留并且在导出文件时会丢失。
查看各种在线示例和 MS 文档,我找不到任何提示上述内容不能按预期工作或需要按顺序设置的 属性在继续下一个 sheet.
之前,使 PageSetup
更改保持不变
我可以将每个 sheet 单独保存为 PDF,然后合并这些 PDF,但在我看来这没有必要。
您观察到的问题是由于 Application.PrintCommunication
属性 使用不当造成的。从您将 PageSetup
设置为 False
的那一刻起,对 PageSetup
的所有更改都会被缓存,直到通过将 属性 值设置回 True
来提交这些更改。但是您在通过 ExportAsFixedFormat
导出工作簿后执行此操作。解决方法很简单:
- 要么不使用
PrintCommunication
- 或在导出
之前将其值设置为True
现在为什么第一个工作表按照您的预期在布局中导出?我只能猜测这是因为它已经保存,并且仅在第一个工作表上配置了宽度收缩:
这里有一些进一步的观察:
- 无需 select/deselect 工作表 before/after 更改其
PageSetup
。
- 无需将第一个工作表作为特例处理。您可以在一个循环中将它们全部设置好。
- 如果工作表配置了高度收缩,我会预先将
FitToPagesTall
设置为 0
(或 False
)。
当然,对 PageSetup
执行多项更改的推荐方法是在 PrintCommunication := False
块内。应用以上内容后,您将获得:
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;
在您的原始代码中,您使用 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 获取更多信息。
我有一个 Delphi 例程,它运行 Excel 文件列表,用 MS Excel 打开它们,遍历 sheets 设置 PageSetup
对应每个 sheet,因此所有列都将适合一页,然后将所有 sheet 导出到单个 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;
如果只有一个 sheet 设置 FitToPagesWide
为 1 页,则按预期工作。但是,如果有多个页面并且说第一页太宽,对第一页的 PageSetup
的更改不会保留并且在导出文件时会丢失。
查看各种在线示例和 MS 文档,我找不到任何提示上述内容不能按预期工作或需要按顺序设置的 属性在继续下一个 sheet.
之前,使PageSetup
更改保持不变
我可以将每个 sheet 单独保存为 PDF,然后合并这些 PDF,但在我看来这没有必要。
您观察到的问题是由于 Application.PrintCommunication
属性 使用不当造成的。从您将 PageSetup
设置为 False
的那一刻起,对 PageSetup
的所有更改都会被缓存,直到通过将 属性 值设置回 True
来提交这些更改。但是您在通过 ExportAsFixedFormat
导出工作簿后执行此操作。解决方法很简单:
- 要么不使用
PrintCommunication
- 或在导出 之前将其值设置为
True
现在为什么第一个工作表按照您的预期在布局中导出?我只能猜测这是因为它已经保存,并且仅在第一个工作表上配置了宽度收缩:
这里有一些进一步的观察:
- 无需 select/deselect 工作表 before/after 更改其
PageSetup
。 - 无需将第一个工作表作为特例处理。您可以在一个循环中将它们全部设置好。
- 如果工作表配置了高度收缩,我会预先将
FitToPagesTall
设置为0
(或False
)。
当然,对 PageSetup
执行多项更改的推荐方法是在 PrintCommunication := False
块内。应用以上内容后,您将获得:
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;
在您的原始代码中,您使用 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 获取更多信息。