将PDF文档重新打印到PDF打印机 - 一般和Delphi特定

时间:2018-01-07 14:07:59

标签: delphi pdf printing pdf-generation

我的系统生成的PDF文档由于某种未知原因而非常大 - 超过1 MB。如果我用PDF打印机(Bullzip,PDF Architect等)将此PDF文档打印到另一个PDF文件,那么生成的PDF文件大小只有40kb,这很好。

所以 - 问题是 - 如何用PDF打印机将PDF文件重新打印到antoher文件。我想拥有与PDF打印机无关的解决方案,让用户选择安装和使用的PDF打印机。

我正在寻找Embarcadero Delphi解决方案,但我也很乐意收到一般性答案(我可以根据Delphi的实施情况调整它们。)

通常每个处理系统(MS office Word或Excel,ReportBuilder)都支持打开特定文件并以静默方式打印它们。但是,显然PDF文件可以由不同的系统打开并打印。共同点是什么?或许我应该坚持使用某些特定的PDF系统并为用户添加额外的要求。

其他细节: 我正在使用Digital Metaphors ReportBuilder和Pragnaan ReportBuilder导出设备http://www.rarefind.com/rbpro/index.html。 Pragnaan需要ppReport - TReport组件和FileName - TmpFileName,代码是一行:

ExportToPDF(ppReport, TmpFileName);

我们正在使用Pragnaan,因为它轻轻地处理非英语语言中的变音符号,但它有制作大文件的缺点。我们坚持使用Pragnaan,因为没有更好的东西,但我们只需要重新打印已经完整的PDF文件。

4 个答案:

答案 0 :(得分:1)

PDF文件未压缩。 从Acrobat Reader或Foxit Reader“保存为”将压缩它。

您还可以在命令行中使用QPDF或类似的应用程序。 https://sourceforge.net/projects/qpdf/files/qpdf/7.0.0/

答案 1 :(得分:1)

我毫不犹豫地发布对第三方库的引用作为q的答案,但除PDFtk外,如果您使用的是ReportBuilder,我建议您在http://www.waler.com/products.htm查看TExtraDevices。

此库呈现为Delphi组件,您将其放在与ReportBuilder组件相同的表单上,并添加选项以将报告输出为多种其他格式,包括PDF。我在D5 / 7时代使用过它,它只是工作了#34;就PDF报告而言:我从未对生成的PDF报告的大小有任何问题,这些报告大多数是几Kb但是ymmv。

它不是免费的(50美元)并且最近没有更新,很大程度上我想象,因为它没有理由 - 至少它自Delphi 2009以来已经更新,所以可用"在右侧" Ascii / Unicode划分。

如果TExtraDevices符合您的要求,则可以避免对报告文件进行任何后期处理。

答案 2 :(得分:0)

我设法找到了部分解决方案。我可以使用Bullzip打印机的COM自动化将PDF文档(大)打印到PDF文档(小):

var BZUtil, BZSettings: OleVariant;
    TmpPrinterName, TmpString: String;
begin
  BZUtil:=CreateOleObject('Bullzip.PdfUtil');
  BZSettings:=CreateOleObject('Bullzip.PdfSettings');

  TmpPrinterName:=BZUtil.DefaultPrinterName;
  BZSettings.SetValue('Output', 'C:\TMP\reprinted_file.pdf');

  BZSettings.SetValue('ShowSettings', 'never');
  BZSettings.SetValue('ShowSaveAS', 'never');
  BZSettings.SetValue('ShowPDF', 'no');
  BZSettings.SetValue('ShowProgress', 'no');
  BZSettings.SetValue('ShowProgressFinished', 'no');
  BZSettings.SetValue('ConfirmOverwrite', 'no');

  BZSettings.SetValue('AfterPrintProgramMode', 'hide');
  BZSettings.SetValue('RunOnSuccessMode', 'hide');
  BZSettings.SetValue('RunOnErrorMode', 'hide');

  //No programs are specified
  //TmpString:=BZSettings.GetValue('RunOnError');
  //MessageDlg('RunOnError: '+TmpString, mtInformation, [mbOK], 0);
  //TmpString:=BZSettings.GetValue('RunOnSuccess');
  //MessageDlg('RunOnSuccess: '+TmpString, mtInformation, [mbOK], 0);
  //TmpString:=BZSettings.GetValue('AfterPrintProgram');
  //MessageDlg('AfterPrintProgram: '+TmpString, mtInformation, [mbOK], 0);
  BZSettings.WriteSettings(True);
  try
    BZUtil.PrintFile('C:\TMP\original_file.pdf', TmpPrinterName);
  except
    on E: Exception do begin
      MessageDlg(E.Message, mtError, [mbOK], 0);
      Exit;
    end;
  end;
  MessageDlg('All is OK', mtInformation, [mbOK], 0);

但是这个解决方案存在一个严重的问题 - PrintFile程序暂时打开新的PDF文件,然后关闭它,但Adobe Acrobat Reader DC主屏幕仍然打开。自动打开Acrobat主屏幕(欢迎消息,最近的文件列表等)是非常烦人的问题,一般没有解决方案,例如在这种情况下,Windows注册表更改https://forums.adobe.com/thread/1812870无法解决问题。我确信Bullzip PrintFile是问题的原因 - 它忽略了需要静默打印的设置。

所以 - 现在只有一个未解决的问题 - 如何在Bullzip静音打印期间处理Acrobat Reader的打开/关闭。我向Bullzip公司提出了错误请求,但处理我的问题需要时间。也许存在一些解决方法?

答案 3 :(得分:0)

PDFForge / PDFCreator COM界面允许以几乎最小的尺寸重新打印静默PDF文件,并保留所有格式和变音符号。

    Queue: IQueue;
    Job: IPrintJob;
    PDFCreator: IPDFCreator;
begin  
    PDFCreator:=CoPdfCreatorObj.Create;
    PDFCreator.AddFileToQueue(AFileName);

    Queue:=CoQueue.Create;
    Queue.Initialize;
    Job:=Queue.NextJob;
    Job.SetProfileByGuid('DefaultGuid');
    Job.SetProfileSetting('OpenViewer', 'False');
    Job.SetProfileSetting('OpenWithPdfArchitect', 'False');
    Job.SetProfileSetting('ShowProgress', 'False');
    Job.SetProfileSetting('ShowQuickActions', 'False');
    //SkipPrintDialog is mentioned in the documentation
    //http://docs.pdfforge.org/pdfcreator/latest/en/pdfcreator/com-interface/reference/settings/
    //but might no be available in free versions of PDFForge/Create, that is why we don't even attempt to use it.
    //Job.SetProfileSetting('SkipPrintDialog', 'True');
    Job.ConvertTo(ANewFileName);

    Queue.ReleaseCom;
end;