我正在尝试修改使用 PDFBOX 加载的 .pdf。我正在使用 RPG,我发现 Java 代码可以从加载的 .pdf 访问页面
PDPage page = (pdpage)pdDoc.getDocumentCatalog().getallPages().get(0)
我看到的另一个代码是
List pages = doc.getDocumentCatalog().getAllPages();
PDPage page = (PDPage)pages.get( i );
我遇到的问题是将代码转换为 RPG。
我现在拥有的代码只是加载我的 .pdf 模板创建一个文档目录并创建我的列表并保存它(XLEnvVar 是我获取类路径的地方)。
/free
XLSEnvVar();
// Load an existing PDF
myPath = jstring_new('/tmp/PDFtemplate.pdf');
File = File_new(myPath);
myDocument = PDdocument_load(File);
myCatalog = PDDocumentCatalog_new(myDocument);
myList = getAllPages(myCatalog);
// Done with this file, so save it
myFile = jstring_new('/tmp/PDFBox-demo.pdf');
PDDocument_save(myDocument:myFile);
// Close the document object in memory to free all allocated space
PDDocument_close(myDocument);
// Done
*INLR = *On;
/end-free
获取原型
D get...
D PR
D EXTPROC(*JAVA:
D 'java.util.List':
D 'get')
上面的原始帖子
我想我会发布我的 PDFBOX 程序,所以互联网上有另一个在 RPG 中使用 PDFBOX 的示例。这是一个完整的示例(它使用我公司的服务程序,而 SQL 只是一个示例 shell,因此如果有人要使用它,他们将不得不更改它们。但我解释了这些服务程序在做什么,以便您可以使用自己的公司服务程序或编写代码来完成这些服务程序所做的事情)。随意拿走这个并将其发布到其他地方,只需留下“编写者”块。希望这可以帮助任何使用 PDFBOX 的人。
h/include QCpySrc,HSpecStd
//*****************************************************************
// Written By: Phillip Simmons Date: 05 20, 2013 *
// Special thanks to Spencer (co-worker) *
// and dhanuxp (code400 forums) and *
// http://wiki.midrange.com/index.php/PDFBox *
// for the intial example that I started with. *
// *
// Purpose: Load a pdf template, modify the template *
// then save the modified document. Using PDFBOX * / //*****************************************************************
/Include QCPYSRC,xCommandP
//Service program to return path on IFS
/Include QCPYSRC,GETIFSPTHP
//Service program to return document name
/Include QCPYSRC,GETIFSNAMP
//Service program for document to adopt authority of the
//folder above
/Include qcpysrc,ifsadoptp
//***************************************************************
// Data structure for SQL statement *
//***************************************************************
D Rcd DS qualified
D EMPLID LIKE(EMPLID)
D LNAME 90A VARYING
D ADDR1 LIKE(ADDR1)
D ADDR2 LIKE(ADDR2)
D CSZ 50A VARYING
D SDS
D ProgramName 1 10
//****************************************************************
// Prototypes for PDFBOX *
// Full documentation of PDFBox is available at *
// http://pdfbox.apache.org/index.html *
// Api Docs http://pdfbox.apache.org/apidocs/ *
//****************************************************************
/Copy QSYSINC/QRPGLESRC,JNI
*Classpath
D XLSEnvVar PR extpgm('XLSENVVAR')
*-----------------------------------------------------------------
* Global Constants
D DEFAULT_USERSPACE_UNIT_DPI...
D C 72
* Page sizes in mm
D PAGE_SIZE_A0 S Like(PDRectangle)
D PAGE_SIZE_A1 S Like(PDRectangle)
D PAGE_SIZE_A2 S Like(PDRectangle)
D PAGE_SIZE_A3 S Like(PDRectangle)
D PAGE_SIZE_A4 S Like(PDRectangle)
D PAGE_SIZE_A5 S Like(PDRectangle)
D PAGE_SIZE_A6 S Like(PDRectangle)
D PAGE_SIZE_A0_LANDSCAPE...
D S Like(PDRectangle)
D PAGE_SIZE_A1_LANDSCAPE...
D S Like(PDRectangle)
D PAGE_SIZE_A2_LANDSCAPE...
D S Like(PDRectangle)
D PAGE_SIZE_A3_LANDSCAPE...
D S Like(PDRectangle)
D PAGE_SIZE_A4_LANDSCAPE...
D S Like(PDRectangle)
D PAGE_SIZE_A5_LANDSCAPE...
D S Like(PDRectangle)
D PAGE_SIZE_A6_LANDSCAPE...
D S Like(PDRectangle)
D PAGE_WIDTH_A0 C 841
D PAGE_HEIGHT_A0 C 1189
D PAGE_WIDTH_A1 C 594
D PAGE_HEIGHT_A1 C 841
D PAGE_WIDTH_A2 C 420
D PAGE_HEIGHT_A2 C 594
D PAGE_WIDTH_A3 C 297
D PAGE_HEIGHT_A3 C 420
*210 orginal size
D PAGE_WIDTH_A4 C 216
*297 orginal size
D PAGE_HEIGHT_A4 C 279
D PAGE_WIDTH_A5 C 148
D PAGE_HEIGHT_A5 C 210
D PAGE_WIDTH_A6 C 105
D PAGE_HEIGHT_A6 C 148
*American pages slightly different size than ISO standard
*-----------------------------------------------------------------
* PDRectangle
D PDRectangleClass...
D C 'org.apache.pdfbox.pdmodel.common.PD-
D Rectangle'
D PDRectangle S O CLASS(*JAVA:PDRectangleClass)
* PDRectangle()
D PDRectangle_new...
D PR like(PDRectangle)
D EXTPROC(*JAVA:
D PDRectangleClass:
D *CONSTRUCTOR)
D width like(jfloat) Value
D height like(jfloat) Value
*-----------------------------------------------------------------
*PDDocumentCatalog
D DocumentCatalog...
D S O CLASS(*JAVA :
D PDDocumentCatalogClass)
D PDDocumentCatalogClass...
D C 'org.apache.pdfbox.pdmodel.PDDocumen-
D tCatalog'
D getDocumentCatalog...
D PR O CLASS(*JAVA :
D PDDocumentCatalogClass)
D EXTPROC(*JAVA :
D PDDocumentClass: 'getDocumen+
D tCatalog' )
*
D getAllPages PR O CLASS(*JAVA : 'java.util.List' )
D EXTPROC(*JAVA :
D PDDocumentCatalogClass : 'get+
D AllPages' )
*-----------------------------------------------------------------
*java.lang.String
D jStringClass...
D C 'java.lang.String'
D jstring_new PR like(jString)
D EXTPROC(*JAVA
D :jStringClass
D :*CONSTRUCTOR)
D create_from 1024A Varying const
*-----------------------------------------------------------------
*PDDocument
D PDDocumentClass...
D C 'org.apache.pdfbox.pdmodel.PDDocumen-
D t'
D PDDocument S O CLASS(*JAVA:PDDocumentClass)
* PDDocument()
D PDDocument_new...
D PR like(PDDocument)
D EXTPROC(*JAVA:
D PDDocumentClass:
D *CONSTRUCTOR)
* PDDocument.addPage()
D PDDocument_addPage...
D PR
D EXTPROC(*JAVA:
D PDDocumentClass:
D 'addPage')
D ppage like(PDPage)
*PDDocument.load()
D PDDocument_load...
D PR like(PDDocument)
D EXTPROC(*JAVA : PDDocumentClass:
D 'load' )
D STATIC
D path like(jstring)
D PDDocument_save...
D PR EXTPROC(*JAVA : PDDocumentClass:
D 'save' )
D savepath like(jstring)
*
D importPage PR O CLASS(*JAVA : 'org.apache.pdfbox.p+
D dmodel.PDPage' )
D EXTPROC(*JAVA : 'org.apache.pdfbox+
D .pdmodel.PDDocument' : 'importPage+
D ' )
D* Parameter prototype declaration for Java type: PDPage
D PDpage like(PDPage)
* PDDocument.close()
D PDDocument_close...
D PR
D EXTPROC(*JAVA:
D PDDocumentClass:
D 'close')
*-----------------------------------------------------------------
* Font Classes
D PDFontClass C 'org.apache.pdfbox.pdmodel.font.PDFo-
D nt'
D PDFont S O CLASS(*JAVA:PDFontClass)
*-----------------------------------------------------------------
* PDPage
D PDPageClass C 'org.apache.pdfbox.pdmodel.PDPage'
D PDPage S O CLASS(*JAVA:PDPageClass)
D PDPage_get PR O CLASS(*JAVA : 'java.lang.Object' )
D EXTPROC(*JAVA : 'java.util.List' :
D 'get' )
D indexNo 10I 0 VALUE
*-----------------------------------------------------------------
* PDType1Font
D PDType1FontClass...
D C 'org.apache.pdfbox.pdmodel.font.PDTy-
D pe1Font'
D PDType1Font S O CLASS(*JAVA:PDType1FontClass)
* PDType1Font()
D PDType1Font_new...
D PR like(PDType1Font)
D EXTPROC(*JAVA:
D PDType1FontClass:
D *CONSTRUCTOR)
D fontname like(jString) Options(*Omit)
* PDType1Font.getStandardFont
D PDType1Font_getStandardFont...
D PR like(PDType1Font)
D EXTPROC(*JAVA:
D PDType1FontClass:
D 'getStandardFont')
D STATIC
D fontname like(jString)
*-----------------------------------------------------------------
* PDPageContentStream
D PDPageContentStreamClass...
D C 'org.apache.pdfbox.pdmodel.edit.PDPa-
D geContentStream'
D PDPageContentStream...
D S O CLASS(*JAVA:
D PDPageContentStreamClass)
* PDPageContentStream()
D PDPageContentStream_new...
D PR like(PDPageContentStream)
D EXTPROC(*JAVA:
D PDPageContentStreamClass:
D *CONSTRUCTOR)
D pdocument like(PDDocument)
D ppage like(PDPage)
D appendcontent N value
D compress N value
* PDPageContentStream.beginText()
D PDPageContentStream_beginText...
D PR
D EXTPROC(*JAVA:
D PDPageContentStreamClass:
D 'beginText')
* PDPageContentStream.setFont()
D PDPageContentStream_setFont...
D PR
D EXTPROC(*JAVA:
D PDPageContentStreamClass:
D 'setFont')
D font like(PDFont)
D fontSize like(jfloat) Value
* PDPageContentStream.moveTextPositionByAmount()
D PDPageContentStream_moveTextPositionByAmount...
D PR
D EXTPROC(*JAVA:
D PDPageContentStreamClass:
D 'moveTextPositionByAmount')
D x like(jfloat) Value
D y like(jfloat) Value
* PDPageContentStream.drawString()
D PDPageContentStream_drawString...
D PR
D EXTPROC(*JAVA:
D PDPageContentStreamClass:
D 'drawString')
D text like(jstring)
* PDPageContentStream.endText()
D PDPageContentStream_endText...
D PR
D EXTPROC(*JAVA:
D PDPageContentStreamClass:
D 'endText')
* PDPageContentStream.close()
D PDPageContentStream_close...
D PR
D EXTPROC(*JAVA:
D PDPageContentStreamClass:
D 'close')
*-----------------------------------------------------------------
* java.awt.Color
D jColorClass...
D C 'java.awt.Color'
D jColor S O CLASS(*JAVA:
D jColorClass)
// new Color(int, int, int)
D jColor_new_fromIntRGB...
D PR like(jColor)
D EXTPROC(*JAVA
D :jColorClass
D :*CONSTRUCTOR)
D R like(jint) value
D G like(jint) value
D B like(jint) value
* PDPageContentStream.setNonStrokingColor(java.awt.Color color)
D PDPageContentStream_setNonStrokingColor...
D PR
D EXTPROC(*JAVA:
D PDPageContentStreamClass:
D 'setNonStrokingColor')
D color like(jColor)
*-----------------------------------------------------------------
* Utilities
D mmToUnits PR Like(jfloat)
D pmm Like(jfloat) Value
D createPageSizes...
D PR
*-----------------------------------------------------------------
*PDFBOX variables
D myFontName S like(jstring)
D myFont S like(PDType1Font)
D myPageContent S like(PDPageContentStream)
D myColor S like(jColor)
D sourceDoc S like(PDDocument)
D targetDoc S like(PDDocument)
D DocumentCat S like(DocumentCatalog)
D pdf_path1 S like(jstring)
D pdf_save S like(jstring)
D myPage S like(PDPage)
D newPage S like(PDPage)
D myAllPages S O CLASS(*JAVA : 'java.util.List' )
D importPageRet S like(PDPage)
*RPG variables
D DocName S 255A VARYING
D pageNumber S 10I 0
D Tdate S d
D Cdate S 10 VARYING
D tempsave S 150 VARYING
D tempload S 150 VARYING
D Directorys S 150 VARYING
D Directoryl S 150 VARYING
D CDirectory S 150 VARYING
D loadstring S 150 VARYING
D checkstring S 150 VARYING
D SqlStm S 1000A VARYING
D Q S 1A INZ(x'7D')
D Cmds S 1500A Varying
D Cmdl S 1500A Varying
D*--------------------------------------------------
D* Procedure name: addText
D* Purpose:
D* Returns:
D* Parameter: myText
D*--------------------------------------------------
D addText PR
D myText 5000A VARYING CONST
D indent 10I 0 CONST
D offset 10I 0 CONST
*
D myString S like(jstring)
/free
Tdate = %Date();
Cdate = %char(Tdate:*usa/);
//The page of the loaded pdf that I am going to want to retrieve
pageNumber = 0;
//Contains the classpath
XLSENVVAR();
//GETIFSPTH AND GETIFSNAM are service programs that my company uses
//to get the path for a document. Further down in PDF_path1(loadstring)
//you can pass a hardcoded string ex PDF_path1('/tmp/demodoc.pdf');
// Get the requested template file
DocName = %Trim(GETIFSPTH(ProgramName:1)) +
%Trim(GETIFSNAM(ProgramName:1));
//Directory the file will be moved into
Directoryl = %Trim(GETIFSPTH(ProgramName:2));
//getting path to load the pdf document
checkstring = %Trim(GETIFSPTH(ProgramName:3)) +
%Trim(GETIFSNAM(ProgramName:3));
//Check to see if template already exists if it does dlt it
//this is needed because later when I move the document to its final
//destination if the document to be moved already exists the move will
//fail. This will cause a modified template to be left behind and when
//the program is ran later the earlier cpy obj will fail and I will
//load an already modified templete.
CallP(E) xCommand('DEL OBJLNK('+Q+%Trim(checkstring)+Q+')');
//String to pass to xcommand()
Cmdl = 'CPY OBJ(' +Q + %trim(DocName) +Q + ')' +
' TODIR(' +Q + %trim(Directoryl) +Q + ')';
xcommand(Cmdl);
//Create a blank pdf document. This will be the page to be modified.
targetDoc = PDDocument_new();
//getting path to load the pdf document
loadstring = %Trim(GETIFSPTH(ProgramName:3)) +
%Trim(GETIFSNAM(ProgramName:3));
//The string that holds the path for where the pdf template is
pdf_path1 = jstring_new(loadstring);
//Load the pdf document
sourceDoc = PDDocument_load(pdf_path1);
//Get the document catalog
DocumentCat = getDocumentCatalog(sourceDoc);
//Get the list of pages
myAllPages = getAllPages(DocumentCat);
//Get the specific page I want
myPage = PDPage_get(myAllPages:pageNumber);
sqlstm = 'SELECT EMPLID,LNAME, ADDR1' +
' ADDR2, CSZ'
' from empmst';
Exec SQL
Prepare S1 From :SqlStm;
Exec SQL
Declare Rcd Cursor for S1;
Exec SQL
Open Rcd;
Exec SQL
Fetch Rcd into :Rcd;
Dow SQLCOD = 0;
//Import and copy to a new page. This is the page to be used
//in the content stream.
importpageret = importpage(targetdoc:myPage);
// Create a content stream so we can add content to the page
// Modifying an existing page so append is *ON
// Compression is *Off
myPageContent = PDPageContentStream_new(targetdoc:importpageret:
*ON:*Off);
//Adding text to preloaded pdf
addtext(Rcd.EMPLID :23 :240);
addtext(Rcd.LNAME :23 :231);
addtext(Rcd.ADDR1 :23 : 227);
addtext(Rcd.ADDR2 :23 : 223);
addtext(Rcd.CSZ :23 : 219);
addtext(Cdate :180 : 240);
EXEC SQL
Fetch Rcd into :Rcd;
ENDDO;
//Temparaly saving to /tmp then will move with mov command
tempsave = %Trim(GETIFSPTH(ProgramName:3)) +
%Trim(GETIFSNAM(ProgramName:3));
//The string that holds the path for where the pdf will be saved
pdf_save = jstring_new(tempsave);
//Done with the file, so save it
PDDocument_save(targetDoc : pdf_save);
// Close the document object in memory to free all allocated space
PDDocument_close(sourceDoc);
PDDocument_close(targetDoc);
//Create the directory that the file will be moved to
CDirectory = %Trim(GETIFSPTH(ProgramName:4))+
%char(%subdt(%date():*YEARS));
xcommand('CRTDIR DIR(' +Q + CDIRECTORY +Q +')');
//retrieve the path the file will be saved to
Directorys = %Trim(GETIFSPTH(ProgramName:4)) +
%char(%subdt(%date():*YEARS)) + '/' +
%Trim(GETIFSNAM(ProgramName:4));
//move the file to the correct directory
Cmds = 'MOV OBJ(' +Q + tempsave +Q + ')' +
' TOOBJ(' +Q + %trim(Directorys)+ Q + ')';
xcommand(Cmds);
//Adopt the auth of the folder
ifsadopt(Directorys);
Exec SQL
Close Rcd;
*Inlr = *On;
/end-free
* mmToUnits
P mmToUnits B
D Pi Like(jfloat)
D pmm value like(jfloat)
D funits S Like(jfloat)
/free
funits = 1 / (25.4) *
DEFAULT_USERSPACE_UNIT_DPI *
pmm;
return funits;
/end-free
P mmToUnits E
* creatPageSizes
P createPageSizes...
P B
D Pi
/free
PAGE_SIZE_A0 = PDRectangle_new(mmToUnits(PAGE_WIDTH_A0):
mmToUnits(PAGE_HEIGHT_A0));
PAGE_SIZE_A1 = PDRectangle_new(mmToUnits(PAGE_WIDTH_A1):
mmToUnits(PAGE_HEIGHT_A1));
PAGE_SIZE_A2 = PDRectangle_new(mmToUnits(PAGE_WIDTH_A2):
mmToUnits(PAGE_HEIGHT_A2));
PAGE_SIZE_A3 = PDRectangle_new(mmToUnits(PAGE_WIDTH_A3):
mmToUnits(PAGE_HEIGHT_A3));
PAGE_SIZE_A4 = PDRectangle_new(mmToUnits(PAGE_WIDTH_A4):
mmToUnits(PAGE_HEIGHT_A4));
PAGE_SIZE_A5 = PDRectangle_new(mmToUnits(PAGE_WIDTH_A5):
mmToUnits(PAGE_HEIGHT_A5));
PAGE_SIZE_A6 = PDRectangle_new(mmToUnits(PAGE_WIDTH_A6):
mmToUnits(PAGE_HEIGHT_A6));
PAGE_SIZE_A0_LANDSCAPE = PDRectangle_new(mmToUnits(PAGE_HEIGHT_A0):
mmToUnits(PAGE_WIDTH_A0));
PAGE_SIZE_A1_LANDSCAPE = PDRectangle_new(mmToUnits(PAGE_HEIGHT_A1):
mmToUnits(PAGE_WIDTH_A1));
PAGE_SIZE_A2_LANDSCAPE = PDRectangle_new(mmToUnits(PAGE_HEIGHT_A2):
mmToUnits(PAGE_WIDTH_A2));
PAGE_SIZE_A3_LANDSCAPE = PDRectangle_new(mmToUnits(PAGE_HEIGHT_A3):
mmToUnits(PAGE_WIDTH_A3));
PAGE_SIZE_A4_LANDSCAPE = PDRectangle_new(mmToUnits(PAGE_HEIGHT_A4):
mmToUnits(PAGE_WIDTH_A4));
PAGE_SIZE_A5_LANDSCAPE = PDRectangle_new(mmToUnits(PAGE_HEIGHT_A5):
mmToUnits(PAGE_WIDTH_A5));
PAGE_SIZE_A6_LANDSCAPE = PDRectangle_new(mmToUnits(PAGE_HEIGHT_A6):
mmToUnits(PAGE_WIDTH_A6));
return;
/end-free
P E
*
*
P*--------------------------------------------------
P* Procedure name: addText
P* Purpose: Write text to a PDPage
P* Returns:
P* Parameter: myText
P*--------------------------------------------------
P addText B
D addText PI
D myText 5000A VARYING CONST
D indent 10I 0 CONST
D offset 10I 0 CONST
*
D myString S like(jstring)
/FREE
// Set font type
myFontName = jstring_new('Times-Roman');
myFont = PDType1Font_getStandardFont(myFontName);
PDPageContentStream_setFont(myPageContent:myFont:10);
// Set the color of the font to add
// This isn't needed if writing to a blank page but since
// adding text to a loaded page need to set the color of the text.
myColor = jColor_new_fromIntRGB(0:0:0);
PDPageContentStream_setNonStrokingColor(myPageContent:myColor);
// Prepare to write text to the content stream
PDPageContentStream_beginText(myPageContent);
// Move the cursor possition,indent is x mm from left of page
// offset x mm from bottom of page.
PDPageContentStream_moveTextPositionByAmount(myPageContent:
mmtounits(indent):mmtounits(offset));
// Create the text string we want to write
myString = jstring_new(myText);
// Write the string to the content stream
PDPageContentStream_drawString(myPageContent:myString);
// We are done writing text to this content stream
PDPageContentStream_endText(myPageContent);
//We are done with this content stream
PDPageContentStream_close(myPageContent);
/END-FREE
P addText E
以为我会在阅读我的代码后添加一些评论。我必须每年制作一个新文件夹。这就是 crtdir 正在做的事情。如果目录已经存在,那么已经创建的目录中的内容是安全的,crtdir 不会覆盖该目录。我将模板从一个位置加载到 /tmp 然后在再次移动之前保存到 /tmp 的原因是,当我使用 PDFBOX 时,jstring_new(' ') 最大为 30 个字符(包括 / 和空格和 . ) . 所以 myString = jstring_new('/tmp/2013/myreportnamethatistoolong.pdf') 该字符串的长度为 39 个字符,并且该字符串将被截断。当我制作字符串时,olong.pdf 将丢失。我可以使用 rpg 代码创建一个字符串并将该字符串传递给 jString_new() 并且长度超过 30 个字符并且它可以工作。