在Delphi Web服务器后生成带有快速报告的PDF [英] Generating PDF with Quick Reports behind a Delphi Web Server

查看:145
本文介绍了在Delphi Web服务器后生成带有快速报告的PDF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一台提供某些Web服务*的Delphi Web服务器。其中一个应该生成并返回PDF报告。



使用QReport创建PDF,然后使用ExportToFilter过程将其导出为PDF文件。 / p>

该例程在应用程序中调用时可以正常运行,但是在TIdTCPServer之后调用时,它将挂起并且永远无法完成。调试它,我有个悬念点:



(注意:我现在到家了,没有源代码。我会尝试重现quickrpt.pas的源代码,就像我记得的一样)。

 过程TCustomReport.ExportToFilter(TQRDocumentFilter过滤); 
...
AProgress:= TQRFormProgress.Create(Application); //挂在这行
AProgress.Owner:= QReport;
如果ShowProgress然后AProgress.Show;
QReport.Client:= AProgress;
...

在网上搜索时,我在此页面(1)设置建议将ShowProgress设置为False,然后编辑代码,以便在将ShowProgress设置为false时(显然,这是由于QReport的线程安全性所致),它不会创建进度表。



因此,我编辑了代码,现在有了:

 过程TCustomReport.ExportToFilter(TQRDocumentFilter filter); 
...
如果ShowProgress然后
开始
AProgress:= TQRFormProgress.Create(Application);
AProgress.Owner:= QReport;
AProgress.Show;
QReport.Client:=进度
结束;
...

现在,报告出来了。但是随后,该服务将变为无效指针异常(我无法跟踪)。对该服务的调用成功完成之后,但是当我关闭该服务**时,它再次因Invalid Pointer Exceptions(无效指针异常)而发出抱怨,然后出现 MyServer提交了无效的操作,必须关闭的Windows消息,然后又出现了两次,然后只是指针异常,然后出现错误216(据我所知,它与Windows访问权限有关。)



谢谢!



更新(1月5日):感谢Scott W.的 answer 。确实,经过一番研究,我发现了另一个建议,即只有主线程才能访问某些组件。因此,我将QR码设置回正常状态,并从TThread内部的Synchronize调用中调用了main方法(这样,主线程便可以处理它)。但是我仍然遇到相同的错误。



您提到您能够使用QR 4将PDF作为服务生成。也许这就是为什么它对我不起作用的原因,因为我m使用QR3。另一方面,您没有提到是在TIdTCPServer之后(这是我的情况,提供Web服务),还是单独运行(例如,在批处理过程中)



有人知道我的QR版本是否有问题?谢谢!



*在Windows XP SP2上运行Delphi 7和QuickReport 3。该服务器基于Indy。



**我有两个版本的服务器:Windows应用程序和Windows服务。两者都调用相同的内部逻辑,并且两个版本都出现问题。



更新(3月8日):毕竟,我的问题是我的打印例程位于另一个dll中,默认的内存管理模块有些糟糕。将我的.dpr的首次使用设置为ShareMem会覆盖Borland实现的内存管理模块,并解决了我的问题。

  
ShareMem,...

(1): http://coding.derkeiler.com/Archive/Delphi/ borland.public.delphi.thirdpartytools.general / 2006-09 / msg00013.html

解决方案

我正在猜测 QReport.Client 在代码的稍后位置使用,并且由于修改后的代码不再将其分配给AProgress,您最终会出错。



确定要修改QuickReport源吗?我已经在Windows服务中使用QuickReport来生成PDF文件,然后将其附加到电子邮件中,并且一切正常,而无需修改QR源。我不记得确切要进行哪些设置,但是它是在Delphi 6和QR 4.06中完成的。


I have a Delphi web server providing some web services*. One of them is supposed to generate and return a PDF report.

The PDF creation is done with a QReport that is then exported into a PDF file with the ExportToFilter procedure.

The routine works fine when called from within an application, but when called behind a TIdTCPServer, it hangs and never finishes. Debugging it, I got tho the hanging point:

(note: I'm home right now and I don't have the source code. I'll try to reproduce quickrpt.pas' source as accurrate as I can remember).

procedure TCustomReport.ExportToFilter(TQRDocumentFilter filter);
  ...
  AProgress := TQRFormProgress.Create(Application); // Hangs on this line
  AProgress.Owner := QReport;
  if ShowProgress then AProgress.Show;
  QReport.Client := AProgress;
  ...

Searching the web, I found in this page (1) the suggestion to set ShowProgress to False, and edit the code so that it does not create the progress form when ShowProgress is set to false (apparently, this is due to QReport not being threadsafe).

So, I edited the code, and now I have this:

procedure TCustomReport.ExportToFilter(TQRDocumentFilter filter);
  ...
  if ShowProgress then
  begin
    AProgress := TQRFormProgress.Create(Application);
    AProgress.Owner := QReport;
    AProgress.Show;
    QReport.Client := AProgress
  end;
  ...

Now, the report comes out. But then the service gets to an Invalid Pointer Exception (which I can't trace). Following calls to the service complete successfully, but when I shut down the service** it starts whining again with Invalid Pointer Exceptions, then the "MyServer has commited an invalid action and must be closed" windows message, then again a couple of times more, then just the pointer exception, then comes to error 216 (which as far as I could find out, is related to Windows access permissions).

Thanks!

Update (jan 5): Thanks Scott W. for your answer. Indeed, after some research, I found another suggestion that only the main thread can access some components. So I set the QR code back to normal and called the main method from a Synchronize call inside a TThread (so that way the main thread would handle it). But I still get the same error.

You mention you were able to generate PDF as a service with QR 4. Maybe that's why it's not working for me, since I'm using QR 3. On the other hand, you don't mention if you're doing that behind a TIdTCPServer (which is my case, providing web services) or if you run it by itself (for instance, during a batch process).

Anybody knows whether my QR version might be the problem? Thanks!

* Running Delphi 7 and QuickReport 3 on a Windows XP SP2. The server is based on Indy.

** I have two versions of the server: a Windows application and a Windows Service. Both call the same inner logic, and the problem occurs with both versions.

Update (mar 8): After all, my problem was that my printing routine was in another dll, and the default memory management module is somewhat crappy. Setting the first uses of my .dpr to be ShareMem overrides the memory management module with Borland's implementation, and solved my problem.

uses
    ShareMem, ...

(1): http://coding.derkeiler.com/Archive/Delphi/borland.public.delphi.thirdpartytools.general/2006-09/msg00013.html

解决方案

I'm guessing that QReport.Client is used somewhere later in the code, and with your modified code no longer assigning it to AProgress, you end up with an error.

Are you sure that you have to modify the QuickReport source? I have used QuickReport in a Windows Service to generate a PDF file and then attach to email message and all worked fine without having to modify the QR source. I don't recall exactly which settings had to be made, but it was done with Delphi 6 and QR 4.06.

这篇关于在Delphi Web服务器后生成带有快速报告的PDF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆