C# 在每个生成的页面之后插入新页面

C# 在每个生成的页面之后插入新页面,c#,pdf,itext7,C#,Pdf,Itext7,我正在使用iText 7库生成一个.pdf文件。我想基本上复制每个页面,最好使用PdfDocumentEvent.END\u页面EventHandler。因为我希望每个页面都是重复的,每个页面都有不同的页眉/页脚 下图将说明所需的结果: 我意识到,通过先生成一个实例,然后使用另一个读写器复制每个页面,并添加带有某种压模的页眉/页脚,可能可以达到预期的效果。 但是由于不同的需求,我想在生成时解决这个问题。但这可能不是我想要的解决方法 我已经试过几次了,但是我有一些奇怪的行为,我自己似乎无法解决这

我正在使用iText 7库生成一个
.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实例,正如您所提到的。如果不想污染磁盘,可以使用字节流。如果您真的想在运行中完成,那么我不会使用布局,而是首先生成所需的页面,然后复制它们,然后通过稍微修改页眉对结果页面重新排序。但同样,高度不可维护的代码。