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 获取更多信息。