Using D6, wPDF 2.x, WPTools 5.x
We are creating a PDF file from a TDBWPRichText.
I know I can use the WPDFExport and it works fine. The WPRichText is properly printed to PDF and looks the same as the screen.
HOWEVER in our case we are printing to PDF from two different reports. One is from Ace Reports and the other is from WPRichText.
So I created a class that inherits from the TWPPDFPrinter and contains several overload methods called MakePDF. One handles the Ace Reports, one handles FastReports, one handles QuickReports and one handles WPTools WPRichText components.
So I simply do the following:
.. Do some report prep work Print2WPDFObj := TPrint2WPDF.Create(Self); Print2WPDFObj.Filename := 'C:\Subcontract.pdf'; Print2WPDFObj.CompressStreamMethod := wpCompressFastFlate; Print2WPDFObj.AutoLaunch := True; Print2WPDFObj.BeginDoc; Print2WPDFObj.MakePDF(aAceReport); Print2WPDFObj.MakePDF(aFastReport); Print2WPDFObj.MakePDF(aQuickReport); Print2WPDFObj.MakePDF(aWPRichText); Print2WPDFObj.EndDoc;
When I look at the output so far all reports look correct except for the WPRichText report. Since this works when I use the WPDFExport then I must be doing something wrong when I use the Print2WPDFObj based on the TWPPDFPrinter. You may ask why I don't use the WPDFExport. Basically because I can't see a way to have all 4 different report types above printed with WPDF into a single document. Anytime I introduced the WPDFExport it seemed to prevent me from having all reports append to each other as expected. So I needed to do everything from the WPPDFPrinter.
So here is the code for the MakePDF when tied to the WPRichText:
procedure TPrint2WPDF.MakePDF(aWPRichText: TWPRichText);var i,w,h : Integer;begin CanvasReference := wprefScreen; i := 0; while i < aWPRichText.CountPages do begin w := aWPRichText.Memo.PaintPageWidth[i]; h := aWPRichText.Memo.PaintPageHeight[i]; StartPage(MulDiv(w, Screen.PixelsPerInch, Screen.PixelsPerInch), MulDiv(h, Screen.PixelsPerInch, Screen.PixelsPerInch), Screen.PixelsPerInch, Screen.PixelsPerInch, 0); try // Use 0 as w and h to let the function calculate the width and height aWPRichText.Memo.PaintRTFPage(i,0,0,0,0,Canvas, [wppInPaintForwPDF] ); finally EndPage; end; inc(i); end;end;
My only guess is the height, width, or Startpage method must not be correctly being used.
I end up with a page size of 7.67 x 6.97in for first page.
I end up with a page size of 7.67 x 1.42in for second page.
but with the WPDFExport
I end up with a page size of 8.5 x 11in for first and second page as expected.
It is possible the problem is due to changes in the WPRichText before printing takes place, but it doesn't cause a problem for the preview tool or the wpdfexport, but is an issue for the wpdfprinter as used above.
Here is what happens right before printing... basically it is prepping header and footer text. This code is what was put in place by co-worker a long while back:
CurrentAppendix := DBWPRTAppendix.DataField; DBWPRTAppendix.DataField := 'AppendixA'; DBWPRTAppendix.ReadOnly := False; DBWPRTAppendix.ClearHeaderFooter; if (NOT DBWPRTAppendix.isEmpty) then begin // Begin Header DBWPRTAppendix.HeaderFooterTextRange := wpraOnAllPages; DBWPRTAppendix.WorkOnText := wpIsHeader; DBWPRTAppendix.CurrAttr.Alignment := paralCenter; DBWPRTAppendix.CurrAttr.DeleteStyle([afsUnderline]); DBWPRTAppendix.CurrAttr.DeleteStyle([afsItalic]); DBWPRTAppendix.CurrAttr.DeleteStyle([afsStrikeOut]); DBWPRTAppendix.CurrAttr.AddStyle([afsBold]); DBWPRTAppendix.CurrAttr.Size := 16; if DBWPRTAppendix.DataField = 'AppendixA' then DBWPRTAppendix.InputString('Appendix "A"'); DBWPRTAppendix.InputString(#13); DBWPRTAppendix.CurrAttr.DeleteStyle([afsBold]); DBWPRTAppendix.CurrAttr.Size := 12; DBWPRTAppendix.InputMergeField('ProjectRE', 'ProjectRE'); DBWPRTAppendix.InputString(#13); DBWPRTAppendix.InputString(#13); DBWPRTAppendix.InputMergeField('CompanyName', 'CompanyName'); DBWPRTAppendix.InputString(#13); DBWPRTAppendix.CurrAttr.Alignment := paralRight; DBWPRTAppendix.InputMergeField('CorresDateHeader', 'CorresDateHeader'); DBWPRTAppendix.InputString(#13); DBWPRTAppendix.InputString('Page '); DBWPRTAppendix.InputTextFieldName('PAGE'); // current page DBWPRTAppendix.InputString(' of '); DBWPRTAppendix.InputTextFieldName('NUMPAGES'); DBWPRTAppendix.InputString(#13); DBWPRTAppendix.CurrAttr.Alignment := paralCenter; // if not dmContract.isCanUserPrintFinal then// SCOOTER ADDED SO CONTRACT ADMINS CAN PRINT DRAFT COPIES TOO if (NOT dmContract.DoPrintAsExecuted) then begin DBWPRTAppendix.InputString('This is NOT a Legal Document! '); DBWPRTAppendix.InputString('Internal Office Use Only!'); DBWPRTAppendix.InputString(#13); DBWPRTAppendix.InputString(#13); end; DBWPRTAppendix.MergeText; // End Header DBWPRTAppendix.WorkOnText := wpIsBody; // Begin Blank Footer DBWPRTAppendix.HeaderFooterTextRange := wpraOnAllPages; DBWPRTAppendix.WorkOnText := wpIsFooter; DBWPRTAppendix.InputString(#13); DBWPRTAppendix.InputString(#13); DBWPRTAppendix.InputString(#13); DBWPRTAppendix.InputString(#13); // End Blank Footer DBWPRTAppendix.WorkOnText := wpIsBody; //Footer DBWPRTAppendix.HeaderFooterTextRange := wpraOnLastPage; DBWPRTAppendix.WorkOnText := wpIsFooter; DBWPRTAppendix.CurrAttr.DeleteStyle([afsUnderline]); DBWPRTAppendix.CurrAttr.DeleteStyle([afsItalic]); DBWPRTAppendix.CurrAttr.DeleteStyle([afsStrikeOut]); DBWPRTAppendix.CurrAttr.AddStyle([afsBold]); DBWPRTAppendix.CurrAttr.Size := 12; DBWPRTAppendix.CurrAttr.Alignment := paralCenter; if DBWPRTAppendix.DataField = 'AppendixA' then DBWPRTAppendix.InputString('End of Appendix "A"'); DBWPRTAppendix.InputString(#13); DBWPRTAppendix.CurrAttr.DeleteStyle([afsBold]); DBWPRTAppendix.CurrAttr.Alignment := paralLeft; DBWPRTAppendix.CurrAttr.Size := 11; //End Footer DBWPRTAppendix.WorkOnText := wpIsBody; DBWPRTAppendix.ReformatAll(True,True);
So do you see any issues here as to why the page size is not properly?
Well... I have my own answer. I examined the WPDFExport code and found settings used there and got the following changes:
procedure TPrint2WPDF.MakePDF(aWPRichText: TWPRichText);
var
i, w, h, xres, yres : Integer;
begin
CanvasReference := wprefScreen;
i := 0;
while i < aWPRichText.CountPages do
begin
// w := aWPRichText.Memo.PaintPageWidth[i];
w := MulDiv(aWPRichText.Memo._PaintPages[i].WidthTw,WPScreenPixelsPerInch,1440);
// h := aWPRichText.Memo.PaintPageHeight[i];
h := MulDiv(aWPRichText.Memo._PaintPages[i].HeightTw,WPScreenPixelsPerInch,1440);
if (w=0) or (h=0) then
begin
w := Round(aWPRichText.Memo.PaintPageWidth[i] / aWPRichText.Memo.CurrentZooming );
h := Round(aWPRichText.Memo.PaintPageHeight[i] / aWPRichText.Memo.CurrentZooming );
end;
xres := aWPRichText.Memo.RTFData.RTFProps.FFontXPixelsPerInch;
yres := aWPRichText.Memo.RTFData.RTFProps.FFontYPixelsPerInch;
StartPage(MulDiv(w, xres, WPScreenPixelsPerInch),
MulDiv(h, yres, WPScreenPixelsPerInch),
xres, yres, 0);
{
StartPage(MulDiv(w, Screen.PixelsPerInch, Screen.PixelsPerInch),
MulDiv(h, Screen.PixelsPerInch, Screen.PixelsPerInch),
Screen.PixelsPerInch, Screen.PixelsPerInch, 0);
}
try
// Use 0 as w and h to let the function calculate the width and height
aWPRichText.Memo.PaintRTFPage(i,0,0,0,0,Canvas, [wppInPaintForwPDF] );
finally
EndPage;
end;
inc(i);
end;
end;
Alles anzeigen
I see the WPDFExport has other things dealing with ConvertJPEGData, ConvertMetafiltToBitMaps, CreateOutlines, CreateThmbnails that I don't take account for with the WPDFPrinter usage, but I am sure I could build that in at a later time.
Right now being able to bring together the different report types we have used throughout various applications was of good use.
One last thing... if there is a way to use the WPDFPrinter for the various report types and still use the WPDFExport for WPTools all the while keeping it all tied to the same BeginDoc / EndDoc so it is still one PDF after printing from multiple report types then please enlighten.