wpview_pdfMergeW, adding a header/footer (and other issues)

  • Delphi 10.1, View v. 4. I'm trying to use the STAMPTEXT to add a footer to each page in a PDF I generate out of several files. The left part of the footer is intended to be the filename, the right a page number.

    Have two ideas: Merging using a string list containing all files, and one appending a file at a time. But I have great problems understanding the Options-part. BTW. what does @ClearText mean? It is mentioned several times but never explained.

    This is what I try:

    Code
    Stamps.Add('PAGENO=ALL');Stamps.Add('@clearText');Stamps.Add('NUMFORMAT=1');Stamps.Add('ORIGIN=2');Stamps.Add('-40,-25=[#]/[##]');Stamps.Add('ORIGIN=3');Stamps.Add(format('40,-25=%s',[PDFDoc.OutputFilename]));

    To start with, I built a string list containing the files to be generated, but then I can't add a footer for each new file. The above works somewhat crappy, as the [##] results in all text is printed on top of each other on page 1, one less on the next page, ending with a correct page at the last page.

    Adding the filename has the same issue.

    Code
    result := false;  ExpCount := 0;{$IFNDEF EMBEDDED}   WPViewPDFLoadDLL('wPDFViewPlus04.dll');{$ENDIF}  List := TStringList.Create;  try    List.QuoteChar := '"';    for PDFDoc in self do    begin      if PDFDoc.IsSupported then      begin        if PDFDoc.IsGenerated then          if not PDFDoc.Generate then            raise Exception.CreateFmt('PDFDoc: %s did not generate',[PDFDoc.OutputFilename]);        with PDFDoc do          if PDFDoc.Generated <> 0.0 then            List.Add(OutputPath + OutputFilename);      end;    end;    if List.Count > 0 then    begin      Stamps := TStringList.Create;      try        Stamps.LineBreak := '\r\n';        Stamps.Add(format('72,32=%s',[fFilename]));        Stamps.Add('@Page numbering part 2 - arabic');        Stamps.Add('NUMFORMAT=1');        Stamps.Add('@cleartext');        Stamps.Add('ORIGIN=2');        Stamps.Add('-40,-25=[#]/[##]');        Options := '"DEBUG=0","DELETESOURCE=1","LOGFILE='+fPath + 'pdfmerge.log","STAMPTEXT='+Stamps.Text+ '"';      finally        Stamps.Free;      end;      ExpCount := wpview_pdfMergeW(PWideChar(List.CommaText)                                  ,PWideChar(fPath + fFilename)                                  ,PWideChar('test')                                  ,PWideChar(WPViewPDF_LicName)                                  ,PWideChar(WPViewPDF_LicKey)                                  ,WPViewPDF_LicCode                                  ,PWideChar(options));      result := ExpCount > 0;    end;  finally    List.Free;  end;

    Then I tried this: Add each file individually

    This didn't work either, and It also is so clumsy that it must be the wrong approach. How do I do this the right way?

    A second issue is that when the PDF is generated, the PDF always triggers a "save form" in the Acrobat Reader. Adding a password (shown above) didn't help. Any ideas to rid this message?

    A final question to something I may have overlooked in the manuals, is how to link the DLL(s?) to the exe-file. Is there a recipe (that works)?

    Thanks in advance.
    Henrik

    Edited once, last by hrc1966 (December 18, 2017 at 10:51 AM).

  • The stamping is implemented as a simple script stored for each page. Internally a string list is stored for each page.

    The ClearText command clears the list, otherwise ach call is appending to the string list.

    The PAGENO selector cause a repetion of all lines until the next PAGENO, NUMFORMAT or NUMOFFSET use. All the lines inbetween will be added to the stamp-list of the selected pages.

    The stampscript is applied after all pages were loaded.

    Your code uses "for PDFDoc in self do" - do you call wpview_pdfMergeW for each file and append to the previous?

    If you need to append multiple pages you need to provide a comma separated list as first parameter and call wpview_pdfMergeW a single time for all files.

    Linking of DLLs to EXE files is not possible. It would be somehow possible to embed the DLL in the resource and extract it on demand but I would not recommend to do this, since such technology would look suspicious to a virus checking program.

    The SaveForm message has to do with the setting of the flag UseAppearances in the PDF.

  • Thanks for the answer.

    Quote: "simple script stored for each page" So if I want to have a "pesudo-footer" on each page in the generated file file, it can't be done? If I understand you correctly, I should add a definition for each page (or range) of the generated file. But I don't know how many pages each merged file contains. Is a possible solution to use pdfGetInfoW to get this information from each file, and build a large STAMPTEXT?

    (File numbering works somewhat OK though).

    The footer should look like this: To the left, filename of the current sub-file, to the right a page number starting from 1 to end of merged PDF-document..

    Quote: "Your code uses "for PDFDoc in self do" - do you call wpview_pdfMergeW for each file and append to the previous?". Yes and no. As I wrote, I tried both but didn't like the one where I append files to the previous. I much more liked feeding it the list of files.

    Quote: "The SaveForm message has to do with the setting of the flag UseAppearances in the PDF." So this is a setting in the PDF's forming the merged PDF? I create several formats out of COM-objects, WP and ImageEn. One must be setting this flag, right?

  • I nailed it! Created this function:

    Code
    function TPDFDoc.GetInformation: integer;const  MAXPAGES = 3000;  PAGESTRUCTSIZE = MAXPAGES shl 1 + MAXPAGES;var  i: integer;  Pages: array of integer;begin  if not assigned(wpview_pdfGetInfoW2) then    raise Exception.Create('Function pdfGetInfoW2 is not available');  SetLength(Pages, PAGESTRUCTSIZE);  result := wpview_pdfGetInfoW2(PWideChar(fOutputPath + fOutputFilename)                              , @Pages[0]                              , PAGESTRUCTSIZE                              , '' // Password                              , PWideChar(WPViewPDF_LicName)                              , PWideChar(WPViewPDF_LicKey)                              , WPViewPDF_LicCode                              , 5);  if result < 0 then    raise Exception.CreateFmt('Cannot open file: %s',[fOutputFilename]);  if result > MAXPAGES then    raise Exception.CreateFmt('Cannot fully scan file: %s',[fOutputFilename]);end;


    And when compiling the PDF, I do this (note that the fStampText.LineBreak is set to '\r\n' when created):


    This produces the result I wanted. Thanks for the sparring. Please comment if my solution can be optimized.