C# 在每个生成的页面之后插入新页面
我正在使用iText 7库生成一个C# 在每个生成的页面之后插入新页面,c#,pdf,itext7,C#,Pdf,Itext7,我正在使用iText 7库生成一个.pdf文件。我想基本上复制每个页面,最好使用PdfDocumentEvent.END\u页面EventHandler。因为我希望每个页面都是重复的,每个页面都有不同的页眉/页脚 下图将说明所需的结果: 我意识到,通过先生成一个实例,然后使用另一个读写器复制每个页面,并添加带有某种压模的页眉/页脚,可能可以达到预期的效果。 但是由于不同的需求,我想在生成时解决这个问题。但这可能不是我想要的解决方法 我已经试过几次了,但是我有一些奇怪的行为,我自己似乎无法解决这
.pdf
文件。我想基本上复制每个页面,最好使用PdfDocumentEvent.END\u页面
EventHandler。因为我希望每个页面都是重复的,每个页面都有不同的页眉/页脚
下图将说明所需的结果:
我意识到,通过先生成一个实例,然后使用另一个读写器复制每个页面,并添加带有某种压模的页眉/页脚,可能可以达到预期的效果。
但是由于不同的需求,我想在生成时解决这个问题。但这可能不是我想要的解决方法
我已经试过几次了,但是我有一些奇怪的行为,我自己似乎无法解决这个问题。我将添加一些代码,希望这也有助于进一步解释这个问题
以下是生成文档的示例代码:
protected void ManipulatePdf(string dest)
{
var writer = new PdfWriter(dest);
var pdfDoc = new PdfDocument(writer);
var doc = new Document(pdfDoc, PageSize.A4);
//Custom EventHandler that adds a page footer
pdfDoc.AddEventHandler(PdfDocumentEvent.END_PAGE, new CustomEndPageEventHandler(pdfDoc));
//The actual generating of the document
for (int i = 0; i < 3; i++)
{
doc.Add(new Paragraph("Test " + (i + 1)));
if (i != 2)
{
doc.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
}
}
/* I would like to add that in reality it is not known exactly when page-breaks will occur */
doc.Close();
}
EPDF(字符串目的地)
{
var编写器=新的PdfWriter(dest);
var pdfDoc=新的PdfDocument(writer);
var doc=新文档(pdfDoc,PageSize.A4);
//添加页脚的自定义EventHandler
pdfDoc.AddEventHandler(PdfDocumentEvent.END_页面,新的CustomEndPageEventHandler(pdfDoc));
//文档的实际生成
对于(int i=0;i<3;i++)
{
添加文件(新段落(“试验”+(i+1));
如果(i!=2)
{
添加文档(新AreaBreak(AreaBreakType.NEXT_PAGE));
}
}
/*我想补充一点,在现实中,不知道何时会出现分页符*/
doc.Close();
}
下面是我到目前为止添加额外页面的代码。请注意,此代码不正确,并给出一些奇怪的行为目前还没有交替使用页眉/页脚的代码,这段代码只是用来在每页之间插入重复项。 我还将在下面添加另一个带有生成结果的图像,但这不是预期的结果
protected class CustomEndPageEventHandler : IEventHandler
{
protected PdfFormXObject placeholder;
protected float side = 20;
protected float x = 300;
protected float y = 25;
protected float space = 4.5f;
protected float descent = 3;
public CustomEndPageEventHandler(PdfDocument pdf) {
placeholder =
new PdfFormXObject(new Rectangle(0, 0, side, side));
}
public void HandleEvent(Event currentEvent)
{
if(!(currentEvent is PdfDocumentEvent docEvent)) return;
var pdf = docEvent.GetDocument();
var page = docEvent.GetPage();
var pageNumber = pdf.GetPageNumber(page);
var pageSize = page.GetPageSize();
var pdfCanvas = new PdfCanvas(
page.GetLastContentStream(), page.GetResources(), pdf);
var canvas = new Canvas(pdfCanvas, pdf, pageSize);
Paragraph p = new Paragraph()
.Add($"{pageNumber}");
canvas.ShowTextAligned(p, x, y, TextAlignment.RIGHT);
pdfCanvas.AddXObject(placeholder, x + space, y - descent);
pdfCanvas.Release();
//Here starts the custom code to insert a duplicate
if ((pageNumber % 2) != 0 && pageNumber < 6)
{
pdf.AddPage(pageNumber + 1, page);
pdf.AddNewPage(pageNumber+2);
}
}
public void WriteTotal(PdfDocument pdf) {
var canvas = new Canvas(placeholder, pdf);
canvas.ShowTextAligned($"/{pdf.GetNumberOfPages()}",0, descent, TextAlignment.LEFT);
}
}
受保护类CustomEndPageEventHandler:IEventHandler
{
受保护的PdfFormXObject占位符;
保护浮子侧=20;
保护浮点数x=300;
保护浮子y=25;
受保护浮动空间=4.5f;
保护浮子下降=3;
公共CustomEndPageEventHandler(PdfDocument pdf){
占位符=
新的PdfFormXObject(新的矩形(0,0,边,边));
}
公共无效HandleEvent(事件当前事件)
{
如果(!(currentEvent为PdfDocumentEvent docEvent))返回;
var pdf=docEvent.GetDocument();
var page=docEvent.GetPage();
var pageNumber=pdf.GetPageNumber(第页);
var pageSize=page.GetPageSize();
var pdfCanvas=新pdfCanvas(
page.GetLastContentStream(),page.GetResources(),pdf);
var画布=新画布(pdfCanvas、pdf、pageSize);
第p段=新的第()段
.Add($“{pageNumber}”);
ShowTextAligned(p,x,y,TextAlignment.RIGHT);
AddXObject(占位符,x+空格,y-下降);
pdfCanvas.Release();
//这里开始自定义代码以插入副本
如果((页码%2)!=0&&pageNumber<6)
{
pdf.AddPage(页码+1,第页);
pdf.AddNewPage(页码+2);
}
}
公共无效书面总计(pdf文档pdf){
var画布=新画布(占位符,pdf);
ShowTextAligned($“/{pdf.GetNumberOfPages()}”,0,下降,TextAlignment.LEFT);
}
}
上面的代码将生成一个新的结果。我尝试了几种不同的方法,例如当您删除行pdf.AddNewPage(pageNumber+2)时代码>然后带有测试2
和测试3
的页面相互重叠
实际上,我一直在想这个问题,我真的很想知道这是否可以在PdfDocumentEvent.END_页面EventHandler中实现,所以我很期待看到你能想出什么办法。这当然是可能的,但需要大量不易维护的代码。因此,我强烈建议使用一个中间文档,然后使用另一个reader+writer实例,正如您所提到的。如果不想污染磁盘,可以使用字节流。如果您真的想在运行中完成,那么我不会使用布局,而是首先生成所需的页面,然后复制它们,然后通过稍微修改页眉对结果页面重新排序。但是,同样的,高度不可维护的代码。这当然是可能的,但需要大量的代码,而这些代码将无法很好地维护。因此,我强烈建议使用一个中间文档,然后使用另一个reader+writer实例,正如您所提到的。如果不想污染磁盘,可以使用字节流。如果您真的想在运行中完成,那么我不会使用布局,而是首先生成所需的页面,然后复制它们,然后通过稍微修改页眉对结果页面重新排序。但同样,高度不可维护的代码。