我使用ColdFusion和iText来生成PDF文档,我希望能够在iText决定进行分页时“自动”向PDF添加页眉和页脚。我已经看到了如何在Java中实现这一点的示例,下面是实现这一点的基本方法:
public class MyHeaderFooterPageEvent extends PdfPageEventHelper {
public void onEndPage(PdfWriter writer, Document document) {
//add your content here
}
}
然后,在开始编写PDF文档之前,您要像他的事件一样“注册”您的事件:
MyHeaderFooterPageEvent event = new HeaderFooterPageEvent();
writer.setPageEvent(event);
(至少据我所知。)
<cfset local.PdfPageEventHelper=CreateObject("java","com.lowagie.text.pdf.PdfPageEventHelper")>
这个解决方案主要基于cfsearching.blogspot.se的这篇旧博客文章。
虽然该解决方案使用javaloader动态代理库,但该解决方案使用较新的(?)函数CreateDynamicProxy(我想可以从ColdFusion 10中获得),它是Ageax(非常感谢!)让我意识到。
这已经在Linux服务器上的ColdFusion 11中成功地测试过了。
<!---call function--->
<cfset _createPdf()>
<!---function for creating pdf with footer that is created via an event handler in onEndPage--->
<cffunction name="_createPdf" output="no" returntype="void">
<cfargument name="pdfFile" type="string" default="document.pdf" hint="the file name to write to disc">
<cfargument name="writeToBrowser" type="boolean" default="true" hint="will open the pdf document in the browser and delete the file when done">
<cfscript>
//set filePath for document
local.filePath = ExpandPath('.')&"/"&arguments.pdfFile;
//get BaseFont
local.BaseFont = CreateObject("java", "com.lowagie.text.pdf.BaseFont");
//get CMYK color
local.CMYKColor = CreateObject("java", "com.lowagie.text.pdf.CMYKColor");
//create color
local.color = local.CMYKColor.init(JavaCast("int",0),JavaCast("int",0),JavaCast("int",0),JavaCast("int",256));
//create font
local.font = local.BaseFont.createFont(local.BaseFont.COURIER, local.BaseFont.CP1252, true);
//compose custom config to make accessable in PdfPageEventHandler.cfc
local.config = {myCustomFooter = {text = "Page number", color = local.color, font = local.font, size = 20}};
//init the event handler (make sure the PdfPageEventHandler.cfc is present in the same folder as this template)
local.eventHandler = CreateObject("component", "PdfPageEventHandler").init(config = local.config);
//we can pass in an array of strings which name all the interfaces we want out dynamic proxy to implement
local.interfaces = ["com.lowagie.text.pdf.PdfPageEvent"];
//create a dynamic proxy that we will pass to the iText writer
local.eventHandlerProxy = CreateDynamicProxy(local.eventHandler, local.interfaces);
//init success flag
local.success = true;
try {
//init document
local.document = CreateObject("java", "com.lowagie.text.Document").init();
//init outstream
local.outputStream = CreateObject("java", "java.io.FileOutputStream").init(local.filePath);
//init writer
local.writer = CreateObject("java", "com.lowagie.text.pdf.PdfWriter").getInstance(local.document, local.outputStream);
//register the PROXY as the page event handler
local.writer.setPageEvent(local.eventHandlerProxy);
//open document
local.document.open();
//init paragraph
local.paragraph = CreateObject("java", "com.lowagie.text.Paragraph");
//output some pages with a simple text message. NOTE that our eventHandler will take care of adding footers on every page - that's the whole point with this example by the way :)
for (local.i = 1; local.i lte 3; local.i = local.i + 1) {
//add paragraph with text
local.document.add(local.paragraph.init("This page should have a footer with a page number on it!"));
//trigger new page
local.document.newPage();
}
} catch (any e) {
//an error occured
WriteOutput("Error: " & e.message);
//set success flag to false
local.success = false;
}
if (StructKeyExists(local, "document")) {
//close document
local.document.close();
}
if (StructKeyExists(local, "outStream")) {
//close outStream
local.outputStream.close();
}
if (local.success && arguments.writeToBrowser) {
_openPdf(filePath=local.filePath);
}
</cfscript>
</cffunction>
<!---function for opening pdf in browser--->
<cffunction name="_openPdf" output="no" returntype="void">
<cfargument name="filePath" type="string" required="yes">
<cfcontent type="application/pdf" file="#arguments.filePath#" deletefile="yes">
</cffunction>
<cfcomponent output="false" hint="iText Event handler used to add headers, footers, etc.">
<!---1. INIT FUNCTION--->
<cffunction name="init" access="public" returntype="PdfPageEventHandler" output="false">
<!---come up with your own arguments that you want to have access to in onEndPage etc--->
<cfargument name="config" type="any" required="true" hint="custom config" />
<!---make sure the config is accessable by other functions--->
<cfset variables.config = arguments.config>
<cfreturn this />
</cffunction>
<!---2. ON END PAGE - the function that is in focus in this example--->
<cffunction name="onEndPage" access="public" returntype="void" output="true" hint="Called when a page is finished, just before being written to the document.">
<cfargument name="writer" type="any" required="true" hint="Writer for the target pdf. Instance of com.lowagie.text.pdf.PdfWriter" />
<cfargument name="document" type="any" required="true" hint="Document for target pdf. Instance of com.lowagie.text.Document" />
<!---edit below to make your own header / footer--->
<cfscript>
local.cb = arguments.writer.getDirectContent();
local.cb.saveState();
local.cb.beginText();
local.cb.setColorFill(variables.config.myCustomFooter.color);
local.cb.setFontAndSize(variables.config.myCustomFooter.font, variables.config.myCustomFooter.size);
local.cb.setTextMatrix(arguments.document.left(), arguments.document.bottom() - 10);
local.text = "#variables.config.myCustomFooter.text# #arguments.writer.getPageNumber()#";
local.cb.showText(local.text);
local.cb.endText();
local.cb.restoreState();
</cfscript>
</cffunction>
<!---3. OTHER FUNCTIONS THAT MUST EXIST (at least in this example)--->
<cffunction name="onOpenDocument" access="public" returntype="void" output="false" hint="Called when the document is opened.">
<cfargument name="writer" type="any" required="true" hint="Writer for the target pdf. Instance of com.lowagie.text.pdf.PdfWriter" />
<cfargument name="document" type="any" required="true" hint="Document for target pdf. Instance of com.lowagie.text.Document" />
<!---To be implemented: Code called when the document is opened--->
</cffunction>
<cffunction name="onCloseDocument" access="public" returntype="void" output="false" hint="Called when the document is closed">
<cfargument name="writer" type="any" required="true" hint="Writer for the target pdf. Instance of com.lowagie.text.pdf.PdfWriter" />
<cfargument name="document" type="any" required="true" hint="Document for target pdf. Instance of com.lowagie.text.Document" />
<!---To be implemented: Code called when the document is closed--->
</cffunction>
<cffunction name="onStartPage" access="public" returntype="void" output="false" hint="Called when a page is initialized.">
<cfargument name="writer" type="any" required="true" hint="Writer for the target pdf. Instance of com.lowagie.text.pdf.PdfWriter" />
<cfargument name="document" type="any" required="true" hint="Document for target pdf. Instance of com.lowagie.text.Document" />
<!---To be implemented: Code called when a page is initialized--->
</cffunction>
<cffunction name="onParagraph" access="public" returntype="void" output="false" hint="Called when a Paragraph is written">
<cfargument name="writer" type="any" required="true" hint="Writer for the target pdf. Instance of com.lowagie.text.pdf.PdfWriter" />
<cfargument name="document" type="any" required="true" hint="Document for target pdf. Instance of com.lowagie.text.Document" />
<cfargument name="paragraphPosition" type="numeric" required="true" hint="The position the chapter will be written to. Value is a java float" />
<!---To be implemented: Code called when paragraph is written --->
</cffunction>
<cffunction name="onParagraphEnd" access="public" returntype="void" output="false" hint="Called when a Paragraph is written">
<cfargument name="writer" type="any" required="true" hint="Writer for the target pdf. Instance of com.lowagie.text.pdf.PdfWriter" />
<cfargument name="document" type="any" required="true" hint="Document for target pdf. Instance of com.lowagie.text.Document" />
<cfargument name="paragraphPosition" type="numeric" required="true" hint="The position the chapter will be written to. Value is a java float" />
<!---To be implemented: Code called on end of paragraph is written--->
</cffunction>
<!---4. FUNCTIONS THAT ONLY NEEDS TO EXIST IF YOU DO SOMETHING THAT TRIGGERS THEM
<cffunction name="OnChapter" access="public" returntype="void" output="false" hint="Called when a Chapter is written">
<cfargument name="writer" type="any" required="true" hint="Writer for the target pdf. Instance of com.lowagie.text.pdf.PdfWriter" />
<cfargument name="document" type="any" required="true" hint="Document for target pdf. Instance of com.lowagie.text.Document" />
<cfargument name="paragraphPosition" type="numeric" required="true" hint="The position the chapter will be written to. Value is a java float" />
<cfargument name="title" type="any" required="true" hint="Title of the chapter. Instance of com.lowagie.text.Paragraph" />
<!---To be implemented: Code called when a Chapter is written--->
</cffunction>
<cffunction name="onChapterEnd" access="public" returntype="void" output="false" hint="Called when the end of a Chapter is reached">
<cfargument name="writer" type="any" required="true" hint="Writer for the target pdf. Instance of com.lowagie.text.pdf.PdfWriter" />
<cfargument name="document" type="any" required="true" hint="Document for target pdf. Instance of com.lowagie.text.Document" />
<cfargument name="position" type="numeric" required="true" hint="The position of the end of the chapter. Value is a java float" />
<!---To be implemented: Code called when the end of a Chapter is reached--->
</cffunction>
<cffunction name="onGenericTag" access="public" returntype="void" output="false" hint="Called when a Chunk with a generic tag is written">
<cfargument name="writer" type="any" required="true" hint="Writer for the target pdf. Instance of com.lowagie.text.pdf.PdfWriter" />
<cfargument name="document" type="any" required="true" hint="Document for target pdf. Instance of com.lowagie.text.Document" />
<cfargument name="rect" type="any" required="true" hint="The Rectangle containing the Chunk. Instance of com.lowagie.text.Rectangle" />
<cfargument name="text" type="string" required="true" hint="The text of the tag" />
<!---To be implemented: Code called when a Chunk with a generic tag is written--->
</cffunction>
<cffunction name="onSection" access="public" returntype="void" output="false" hint="Called when a Section is written">
<cfargument name="writer" type="any" required="true" hint="Writer for the target pdf. Instance of com.lowagie.text.pdf.PdfWriter" />
<cfargument name="document" type="any" required="true" hint="Document for target pdf. Instance of com.lowagie.text.Document" />
<cfargument name="paragraphPosition" type="numeric" required="true" hint="The position the chapter will be written to. Value is a java float" />
<cfargument name="depth" type="numeric" required="true" hint="The number depth of the Section. Value is a java int" />
<cfargument name="title" type="any" required="true" hint="Title of the section. Instance of com.lowagie.text.Paragraph" />
<!---To be implemented: Code called when a Section is written--->
</cffunction>
<cffunction name="onSectionEnd" access="public" returntype="void" output="false" hint="Called when the end of a Section is reached.">
<cfargument name="writer" type="any" required="true" hint="Writer for the target pdf. Instance of com.lowagie.text.pdf.PdfWriter" />
<cfargument name="document" type="any" required="true" hint="Document for target pdf. Instance of com.lowagie.text.Document" />
<cfargument name="paragraphPosition" type="numeric" required="true" hint="The position the chapter will be written to. Value is a java float" />
<cfargument name="depth" type="numeric" required="true" hint="The number depth of the Section. Value is a java int" />
<cfargument name="title" type="numeric" required="true" hint="Title of the section. Instance of com.lowagie.text.Paragraph" />
<!---To be implemented: Code called when the end of a Section is reached--->
</cffunction>
--->
</cfcomponent>
更新!
这里是相同的cfc,但在纯cfscript中,对于更喜欢这样的您来说:
<cfscript>
component output="false" hint="iText Event handler used to add headers, footers, etc." {
property name="config" type="struct";
//1. INIT FUNCTION
public PdfPageEventHandler function init(required any config) {
//make sure the config is accessable by other functions
variables.config = arguments.config;
return this;
}
//2. ON END PAGE - the function that is in focus in this example
public void function onEndPage(required any writer, required any document) {
//Called when a page is finished, just before being written to the document
//edit below to make your own header / footer
local.cb = arguments.writer.getDirectContent();
local.cb.saveState();
local.cb.beginText();
local.cb.setColorFill(variables.config.myCustomFooter.color);
local.cb.setFontAndSize(variables.config.myCustomFooter.font, variables.config.myCustomFooter.size);
local.cb.setTextMatrix(arguments.document.left(), arguments.document.bottom() - 10);
local.text = "#variables.config.myCustomFooter.text# #arguments.writer.getPageNumber()#";
local.cb.showText(local.text);
local.cb.endText();
local.cb.restoreState();
}
//3. OTHER FUNCTIONS THAT MUST EXIST (at least in this example)
public void function onOpenDocument(required any writer, required any document) {
//Called when the document is opened
}
public void function onCloseDocument(required any writer, required any document) {
//Called when the document is closed
}
public void function onStartPage(required any writer, required any document) {
//Called when a page is initialized
}
public void function onParagraph(required any writer, required any document, required numeric paragraphPosition) {
//Called when a Paragraph is written
//paragraphPosition - The position the chapter will be written to. Value is a java float
}
public void function onParagraphEnd(required any writer, required any document, required numeric paragraphPosition) {
//Called when a Paragraph is written
//paragraphPosition - The position the chapter will be written to. Value is a java float
}
//4. FUNCTIONS THAT ONLY NEEDS TO EXIST IF YOU DO SOMETHING THAT TRIGGERS THEM
public void function OnChapter(required any writer, required any document, required numeric paragraphPosition, required any title) {
//Called when a Chapter is written
//paragraphPosition - The position the chapter will be written to. Value is a java float
//title - Title of the chapter. Instance of com.lowagie.text.Paragraph
}
public void function onChapterEnd(required any writer, required any document, required numeric position) {
//Called when the end of a Chapter is reached
//position - The position of the end of the chapter. Value is a java float
}
public void function onGenericTag(required any writer, required any document, required any rect, required string text) {
//Called when a Chunk with a generic tag is written
//rect - The Rectangle containing the Chunk. Instance of com.lowagie.text.Rectangle
//text - The text of the tag
}
public void function onSection(required any writer, required any document, required numeric paragraphPosition, required numeric depth, required any title) {
//Called when a Section is written
//paragraphPosition - The position the section will be written to. Value is a java float
//depth - The number depth of the Section. Value is a java int
//title - Title of the section. Instance of com.lowagie.text.Paragraph
}
public void function onSectionEnd(required any writer, required any document, required numeric paragraphPosition, required numeric depth, required any title) {
//Called when the end of a Section is reached
//paragraphPosition - The position the section will be written to. Value is a java float
//depth - The number depth of the Section. Value is a java int
//title - Title of the section. Instance of com.lowagie.text.Paragraph
}
}
</cfscript>
使用iTextSharp,您可以通过将事件附加到PDF来向PDF添加页眉/页脚,如本SO答案中所述:https://stackoverflow.com/a/19004392 我怎样才能用 iText 7 做同样的事情? 这个链接有Java代码示例,但看起来不像它使用的页面事件。
` 在此输入代码
问题内容: 在我的pdf文件中,我需要有多个页眉和页脚。在页眉中,我希望标题标题位于左侧,而某些文本位于中心。 同样,在页脚中,我需要在左侧打印公司名称,在中心打印页码,并在右侧打印有关表格内容的一些信息。 我看过很多文章,但是我没有正确的想法来创建它,有人请帮助我提供一些示例代码片段。 问题答案: 页眉和页脚应使用“页面事件”添加。如果您需要一些示例,只需在官方网站上查找关键字header /
问题内容: 我正在尝试使用具有以下代码的iText 7创建PDF文档,并且生成时,我的PDF文档内容在同一页面中重叠(即,在第1页中)。 我看到了 document.newPage(); iText 7中缺少该方法。如何在itext 7中不使用pdfDocumet.copyPages(…)或PDFmerger将页面添加到我的PDF文档中。 问题答案: 在iText 7中,该方法已成为区域中断的特殊
问题内容: 如何在我的PDF页面中添加 页眉 和 页脚 ?我想要一个表,表头中有3列,其他表中,页脚中有3列。我的页面可能是A3或A4,并且是横向或纵向。 谁能帮我?我在互联网上找不到很好的例子。 谢谢! mas正 问题答案: 创建一个MyPageEventListener类,该类扩展了 PdfPageEventHelper 将页面事件侦听器添加到PdfWriter对象 在MyPageEventL