访问我加载的 .pdf 页面(使用 pdfbox)(我正在使用 RPG)
Posted
技术标签:
【中文标题】访问我加载的 .pdf 页面(使用 pdfbox)(我正在使用 RPG)【英文标题】:Access the page of a .pdf I load (using pdfbox) (and i'm using RPG) 【发布时间】:2013-05-08 16:01:18 【问题描述】:我正在尝试修改使用 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
我想在阅读我的代码后添加几个 cmets。我必须每年制作一个新文件夹。这就是 crtdir 正在做的事情。如果目录已经存在,那么已经创建的目录中的内容是安全的,crtdir 不会覆盖该目录。我将模板从一个位置加载到 /tmp 然后在再次移动之前保存到 /tmp 的原因是,当我使用 PDFBOX 时,jstring_new(' ') 最多包含 30 个字符(包括 / 和空格和 . ) .所以 myString = jstring_new('/tmp/2013/myreportnamethatistoolong.pdf') 该字符串的长度为 39 个字符,并且该字符串将被截断。当我制作字符串时,olong.pdf 将丢失。我可以用 rpg 代码创建一个字符串并将该字符串传递给 jString_new() 并且长度超过 30 个字符并且它可以工作。
【问题讨论】:
希望为大家解释清楚。我可能已经过度解释了某些方面,但作为一名刚接触该语言并且刚接触专业水平编程的程序员,会有一些我不明白的部分,因为“每个人都知道”代码做了什么,所以试图解释得足够多,即使是新人可以看到疯狂背后的方法。如果有人有任何问题可以随时提问,我会尽力回答。删除了我的一些原始帖子以进行编辑,但没有什么重要的 【参考方案1】:你会希望你的 List.get() 返回org.apache.pdfbox.pdmodel.PDPage
RPG 是强类型的,所以我们不能像Java 那样强制转换。相反,我们创建原型以返回我们想要操作的对象。按照这些思路,您最终可能会使用 get() 来检索几种不同类型的 List 元素。 RPG 也不做重载。我要做的是为我要处理的每个对象创建一个单独的 get() 原型。所以我有一个 getPage() 和一个 getThread() 等等。每个都是 'java.util.List:get' 但返回不同的对象类型。
www.midrange.com 上的 RPG 列表是另一个很好的 RPG 帮助来源。
【讨论】:
以上是关于访问我加载的 .pdf 页面(使用 pdfbox)(我正在使用 RPG)的主要内容,如果未能解决你的问题,请参考以下文章
PDFBOX 2.0.18 - 如何遍历 PDF 页面并检索特定字段