如何用iText添加每页的总页数?

有帮助吗?

解决方案

  1. 处理a的输出 PdfWriter 到一个 bytestream 首先是虚拟页数。
  2. 创建一个 PdfReader 从那 bytestream, 呼叫 PdfReader.getNumberOfPages 获取实际页数。
  3. 重新创建 PDF 输出,了解页数,并相应地更改页脚。

这很混乱,但如果不采用两次方法,就没有简单的方法可以知道页数。请参阅 示例代码 有关操作 PDF 的详细信息。

其他提示

可以创建从PdfPageEventHelper继承的类 然后覆盖论文两个功能是这样的:

Imports System.Collections.Generic
Imports System.Text

Imports iTextSharp.text.pdf
Imports iTextSharp.text

Namespace PDF_EnteteEtPiedDePage
    Public Class EnteteEtPiedDePage
        Inherits PdfPageEventHelper
        ' This is the contentbyte object of the writer
        Private cb As PdfContentByte

        ' we will put the final number of pages in a template
        Private template As PdfTemplate

        ' this is the BaseFont we are going to use for the header / footer
        Private bf As BaseFont = Nothing

        ' This keeps track of the creation time
        Private PrintTime As DateTime = DateTime.Now

        ' we override the onOpenDocument method
        Public Overrides Sub OnOpenDocument(writer As PdfWriter, document As Document)
            Try
                PrintTime = DateTime.Now
                bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED)
                cb = writer.DirectContent
                template = cb.CreateTemplate(50, 50)
            Catch de As DocumentException
            Catch ioe As System.IO.IOException
            End Try
        End Sub

        Public Overrides Sub OnStartPage(writer As PdfWriter, document As Document)
            MyBase.OnStartPage(writer, document)

            Dim pageSize As Rectangle = document.PageSize

        End Sub

        Public Overrides Sub OnEndPage(writer As PdfWriter, document As Document)
            MyBase.OnEndPage(writer, document)

            Dim pageN As Integer = writer.PageNumber
            Dim text As [String] = "Page " & pageN & " de "
            Dim len As Single = bf.GetWidthPoint(text, 8)

            Dim pageSize As Rectangle = document.PageSize

            cb.SetRGBColorFill(100, 100, 100)

            cb.BeginText()
            cb.SetFontAndSize(bf, 8)
            cb.SetTextMatrix(pageSize.GetLeft(40), pageSize.GetBottom(30))
            cb.ShowText(text)
            cb.EndText()

            cb.AddTemplate(template, pageSize.GetLeft(40) + len, pageSize.GetBottom(30))

            cb.BeginText()
            cb.SetFontAndSize(bf, 8)
            cb.ShowTextAligned(PdfContentByte.ALIGN_RIGHT, "Imprimé le : " & PrintTime.ToShortDateString() & " à " & PrintTime.ToShortTimeString, pageSize.GetRight(40), pageSize.GetBottom(30), 0)
            cb.EndText()
        End Sub

        Public Overrides Sub OnCloseDocument(writer As PdfWriter, document As Document)
            MyBase.OnCloseDocument(writer, document)

            template.BeginText()
            template.SetFontAndSize(bf, 8)
            template.SetTextMatrix(0, 0)
            template.ShowText("" & Convert.ToString((writer.PageNumber - 1)))
            template.EndText()
        End Sub

    End Class
End Namespace

然后后,仅仅设定pdfwriter PageEvent的值是这样的:

Dim PageEventHandler = New EnteteEtPiedDePage()
            aPdfWriter.PageEvent = PageEventHandler

没有更多的搜索,这里是解决方案。如果他们删除此链接,我将代码发布到我的网站和主机的链接。

iText的页码例如

下面是我使用的代码。它不会增加太多的开销编写的页面输出。

outputStream = new ByteArrayOutputStream();
output = new DataOutputStream(outputStream);
document = new Document();
writer = PdfWriter.getInstance(document, output);
document.open();
contentByte = writer.getDirectContent();
....add stuff
document.close();
writer.close();
byte[] output = outputStream.toByteArray();
PdfReader reader = new PdfReader(output);
//reset the output
outputStream = new ByteArrayOutputStream();
output = new DataOutputStream(outputStream);
document = new Document();
writer = PdfWriter.getInstance(document, output);
document.open();
PdfStamper stamper = new PdfStamper(reader, outputStream);
//add the pages
for (int i = 1; i <= pageCount; i++)
{
    contentByte = stamper.getOverContent(i);
    addParagraph("Page " + i + " of " + pageCount, new Point(500, 30), boldTextFont);  // my own paragraph font
}
stamper.close();

这是一个快速的网络搜索,以提醒自己此;看一看

实施例

在相关方法onEndPage()产生的“X”和onCloseDocument()以产生“Y”,一旦你命中文档的末尾。

下面是一个方便的功能! (上米尔豪斯的做法基于)(这使用iText的版本4.1.6.0)

public static byte[] AddPageNumbers(byte[] pdf)
        {
            PdfReader reader = new PdfReader(pdf);
            var Pages = reader.NumberOfPages;
            MemoryStream ms = new MemoryStream();

            PdfStamper stamper = new PdfStamper(reader, ms);
            for (int i = 1; i <= Pages; i++)
            {
                PdfContentByte overContent;
                Font Signature = FontFactory.GetFont("Calibiri", 9, iTextSharp.text.Font.NORMAL, Color.BLACK);
                overContent = stamper.GetOverContent(i);
                var helv = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED);
                overContent.SaveState();
                overContent.BeginText();
                overContent.SetFontAndSize(helv, 10.0f);
                overContent.SetTextMatrix(PageSize.LETTER.Width / 2 - 20, PageSize.LETTER.Height - (PageSize.LETTER.Height - 20));
                overContent.ShowText("Page " + (i) + " of " + Pages);
                overContent.EndText();
                overContent.RestoreState();
            }
            stamper.Close();            
            return ms.ToArray();
        }

试试这个,因为我也是从这个痛苦,我也有新的这个库中,以便以后很多的麻烦,我得到的结果仅仅只尝试,因为我在评论中提到的应用逻辑的两倍。

class PdfReportServlet extends HttpServlet
{
    public static int total = 0;

    public static int getTotal() 
    {
        return total;
    }

    public static void setTotal(int total) {
        PdfReportServlet .total = total;
    }


    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    {
        String reportFor = request.getParameter("report");
        if(!"".equals(reportFor))
        {
            if(reportFor.equals("pdf"))
            {
    /* 
       from here logic starts
    */
                response.setContentType("application/pdf");
                Document document = new Document(PageSize.LETTER.rotate());
                try
                {
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    PdfWriter pdfWriter = PdfWriter.getInstance(document, bos);
                    PdfReport pdfReport = new PdfReport();
                    pdfWriter.setPageEvent(pdfReport);
                    document.open();
                    String id = request.getParameter("id");
                    DettagliFamigliaPDFReport.generatePDFReport(document,id);
                    document.close();

                    /*
                     * now again give new references to Document and PdfWriter classes.
                     */

                    document = new Document(PageSize.LETTER.rotate());

                    pdfWriter = PdfWriter.getInstance(document, response.getOutputStream());
                    PDFReport.setTotalPages(getTotal());/*##PAGES_TOTAL here i set total Pages which i get from above logic */
                    PdfReport pdfReport = new PdfReport();
                    pdfWriter.setPageEvent(pdfReport);
                    document.open();
                    id = request.getParameter("id");
                    PDFReport.generatePDFReport(document,id);
                    document.close();

                }
                catch(DocumentException de){
                    de.printStackTrace();
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }


}


/*
    Here below i write the class inherits the PdfPageEventHelper class and also having generatePDFReport() method.
*/


public class PDFReport extends PdfPageEventHelper
{
    public static PdfTemplate template;
    public static int totalPages=0;

    public static int getTotalPages() {
        return totalPages;
    }

    public static void setTotalPages(int totalPages) {
        DettagliFamigliaPDFReport.totalPages = totalPages;
    }


    public static void generatePDFReport(Document document,String id)
    {
        // here your data to write on page of pdf.
    }

    @Override
    public void onOpenDocument(PdfWriter writer, Document doc) 
    {
        template = writer.getDirectContent().createTemplate(100, 100);
    }

    int totalPage = 0;
    @Override
    public void onCloseDocument(PdfWriter writer, Document doc) 
    {
        totalPage = writer.getPageNumber() - 1;/* at the end this method calls and you will get total number of pages.*/
        PdfReportServlet.setTotal(totalPage); /* while first time logic of servlet executes then i set the total pages to servlet's variable using this logic.
and second time servlet's logic is executing i passed totalPages to this class variable
where i marked ##PAGES_TOTAL  */
    }

    @Override
    public void onStartPage(PdfWriter writer, Document doc) {
        // Here i write header logic when each time page starts.
    }

    @Override`enter code here`
    public void onEndPage(PdfWriter writer, Document doc) 
    {
        Rectangle rect = writer.getPageSize();
        float width = rect.getWidth()/2;   

        DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
        Date date = new Date();

        String footerOne = "This document is printed on date "+dateFormat.format(date)+" - Page. "+writer.getPageNumber()+" of "+getTotalPages();

        Paragraph paraOne = new Paragraph(footerOne);

        Font fontFooter = new Font();
        fontFooter.setSize(8);
        fontFooter.setColor(Color.gray);

        paraOne.setFont(fontFooter);

        Phrase footerPhraseOne = new Phrase(paraOne);
        ColumnText.showTextAligned(writer.getDirectContent(),
                Element.ALIGN_CENTER, footerPhraseOne,
                width, 30, 0);
    }
}

这是您的代码片段:

final PdfWriter writer = PdfWriter.getInstance(document, outputStream);
writer.setPageEvent(new PageStamper());

以及编号代码:

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.itextpdf.tool.xml.*;
import com.itextpdf.tool.xml.css.*;

import java.io.IOException;

/**
 * Adds page number to al the pages except the first.
 */
public class PageStamper extends PdfPageEventHelper {
    private static final Logger logger = Logger.getLogger(PageStamper.class);

    @Override
    public void onEndPage(PdfWriter writer, Document document) {
        final int currentPageNumber = writer.getCurrentPageNumber();

        if (currentPageNumber == 1) {
            return;
        }

        try {
            final Rectangle pageSize = document.getPageSize();
            final PdfContentByte directContent = writer.getDirectContent();

            directContent.setColorFill(BaseColor.GRAY);
            directContent.setFontAndSize(BaseFont.createFont(), 10);

            directContent.setTextMatrix(pageSize.getRight(40), pageSize.getBottom(30));
            directContent.showText(String.valueOf(currentPageNumber));

        } catch (DocumentException | IOException e) {
            logger.error("PDF generation error", e);
        }
    }
}

这段代码在这里找到: http://blog.abelsky.com/2014/01/22/adding-page-number-to-itext- generated-pdf/. 。非常感谢你,andy722

至于其他的答案表明,你首先需要创建PDF,然后看你创建的PDF多少页包含然后页脚添加到每个页面。 理想的类做,这是PdfStamper,其目的是为了附加元素添加到现有的PDF /现有的PDF页面。

下面是一种基于米尔豪斯的例子的详细的示例:

Font smallFont = FontFactory.getFont("Arial", 9, Font.NORMAL);
ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream();
Document document = new Document(PageSize.A4, 70, 70, 40, 40);
PdfWriter pdfWriter = PdfWriter.getInstance(document, pdfOutputStream);

document.open();
//CREATE PDF HERE - ADD CONTENT TO DOCUMENT
document.close();

int pageCount = pdfWriter.getPageNumber()-1;
byte[] pdfAsBytes = pdfOutputStream.toByteArray();

//add footer
PdfReader reader = new PdfReader(pdfAsBytes);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(outputStream);
document = new Document();
document.open();
PdfStamper stamper = new PdfStamper(reader, output);
for (int i = 1; i <= pageCount; i++) {
  ColumnText.showTextAligned(stamper.getOverContent(i), 
    Element.ALIGN_CENTER, new Phrase(i+"/" + pageCount, smallFont), 550, 30, 0);
}
stamper.close();
byte[] finalPdfAsBytes = outputStream.toByteArray();

这是在Java中转换的拉马码(它的一部分至少)

public class test extends PdfPageEventHelper{
    private int _pg = 0;
    private BaseFont font;

    @Override
    public void onEndPage(PdfWriter writer, Document document) {
        _pg++;
        PdfContentByte cb = writer.getDirectContent();
        cb.beginText();
        try {
            Rectangle pageSize = document.getPageSize();
            cb.setFontAndSize(font, 8);
            cb.setTextMatrix(pageSize.getLeft(40), pageSize.getBottom(15));
            String s = "Page " + _pg + "/";
            cb.showText(s);
            cb.addTemplate(template, pageSize.getLeft(40) + font.getWidthPoint(s, 8), pageSize.getBottom(15));
        } catch (Exception exc) {
            logger.warn("got Exception : " + exc.getMessage());
        }
        cb.endText();
    }

    @Override
    public void onOpenDocument(PdfWriter writer, Document document) {
        super.onOpenDocument(writer, document);
        template = writer.getDirectContent().createTemplate(50, 50);
        try {
            font = BaseFont.createFont(BaseFont.COURIER, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED);
        } catch (Exception exc) {
            logger.warn("got Exception : " + exc.getMessage());
        }
    }

    @Override
    public void onCloseDocument(PdfWriter writer, Document document) {
        super.onCloseDocument(writer, document);

        template.beginText();
        try {
            template.setFontAndSize(font, 8);
            template.setTextMatrix(0f, 0f);
            template.showText("" + (writer.getPageNumber() - 1));
        } catch (Exception ex) {
            logger.error(ex);
        }
        template.endText();
    }

}

经过两天的努力!我最终得到的页面总数的PDF计数。 其实我的客户要求是为了显示页脚只有PDF的最后一页上。 这就是我这样做,希望这将帮助有前途。 第1步: 创建新类,将继承的 PdfPageEventHelper 就这样。

public class ITextEvents : PdfPageEventHelper
{
public int pageNos { get; set; }

/// <summary>
/// CALLED ON EACH PAGE END PAGE, 
/// </summary>
/// <param name="writer"></param>
/// <param name="document"></param>
public override void OnEndPage(iTextSharp.text.pdf.PdfWriter writer, iTextSharp.text.Document document)
{
//LOGIC: TO SHOW DISCLAIMER ONLY ON LAST PAGE
if (document.PageNumber == pageNos)
{
//Create new Paragraph
Paragraph p = new Paragraph();
//ADD CHUNK IN PARAGRAPH
p.Add(new Chunk("Heading-Text: ", FontFactory.GetFont("Calibri",11,Font.BOLD)));
p.Add(new Chunk("Details sow in footer", FontFactory.GetFont("Calibri", 10)));
//PARAGRAPH TEXT ALIGNMENT. 
p.Alignment = Element.ALIGN_LEFT;
//CREATE PDF TABLE, FOR ADDING NEW CELL AND ROW IN THE PDF
PdfPTable footerTbl = new PdfPTable(1);
//SETING TABLE WIDTH
footerTbl.TotalWidth = 580;
footerTbl.HorizontalAlignment = Element.ALIGN_LEFT;
//ADDING CELL IN THE TABLE
PdfPCell cell = new PdfPCell(p);
//CELL LAYOUT DESIGN
cell.Border = 1;
cell.PaddingLeft = 10;
cell.PaddingRight = 10;
footerTbl.AddCell(cell);
//ADDING TABLE IN THE PDF
footerTbl.WriteSelectedRows(0, -1, 10, 110, writer.DirectContent);
}
}

/// <summary>
/// THIS METHOD WILL GET TOTAL PDF PAGES COUNT,
/// REQUIREMENT OF THIS METHOD WAS IS TO SHOW FOOTER ON LAST PAGE IN THE PDF. 
/// </summary>
/// <param name="HistoryHTML"></param>
/// <param name="Name"></param>
/// <param name="filePath"></param>
/// <returns></returns>
public int GetTotalPageCount(string HistoryHTML, String Name, string filePath)
{
try
{
using (MemoryStream stream = new System.IO.MemoryStream())
{
StringReader sr = new StringReader(HistoryHTML);
Document pdfDoc = new Document(PageSize.A4, 30f, 30f, 30f, 90f);
PdfWriter writer = PdfWriter.GetInstance(pdfDoc, stream);
pdfDoc.Open();
XMLWorkerHelper.GetInstance().ParseXHtml(writer, pdfDoc, sr);
pdfDoc.Close();

bool exists = System.IO.Directory.Exists(filePath);
if (!exists)
    System.IO.Directory.CreateDirectory(filePath);
System.IO.File.WriteAllBytes((filePath + @"\FileName-" + Name + ".pdf"), stream.ToArray());

string path = AppDomain.CurrentDomain.BaseDirectory + @"FolderPath\" + "FileName-" + Name + ".pdf";

PdfReader pdfReader = new PdfReader(path);
int numberOfPages = pdfReader.NumberOfPages;
pdfReader.Close();
stream.Close();
return numberOfPages;

}
}
catch (Exception ex)
{
CommonFunction.logElmahError(ex);
}
return -1;
}
}  

在从流产生pdf文件,调用此方法以获得总页数。

int pageCount = new Common.ITextEvents().GetTotalPageCount(HistoryHTML, Name, Server.MapPath("~/FolderPath"));

为了更好地理解我提供控制器端代码。

public string ExportPDF(string HistoryHTML, String Name)
        {
            int pageCount = new Common.ITextEvents().GetTotalPageCount(HistoryHTML, Name, Server.MapPath("~/FolderPath"));

            using (MemoryStream stream = new System.IO.MemoryStream())
            {
                StringReader sr = new StringReader(HistoryHTML);
                Document pdfDoc = new Document(PageSize.A4, 30f, 30f, 30f, 30f);
                PdfWriter writer = PdfWriter.GetInstance(pdfDoc, stream);
                pdfDoc.Open();

                //APPEND DISCLAIMER TEXT ACCORING TO HIPAA RULES.
                writer.PageEvent = new Common.ITextEvents() { pageNo = pageCount };

                XMLWorkerHelper.GetInstance().ParseXHtml(writer, pdfDoc, sr);
                pdfDoc.Close();

                bool exists = System.IO.Directory.Exists(Server.MapPath("~/FolderPath"));
                if (!exists)
                    System.IO.Directory.CreateDirectory(Server.MapPath("~/FolderPath"));
                System.IO.File.WriteAllBytes(Server.MapPath("~/FolderPath/" + Name + ".pdf"), stream.ToArray());

                return File(stream.ToArray(), "application/pdf", "FileName-" + Name + "-" + Name + ".pdf");
            }
        }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top