代码之家  ›  专栏  ›  技术社区  ›  trunkc

如何在带有IText的每页上添加总页数?

  •  22
  • trunkc  · 技术社区  · 17 年前

    如何在带有IText的每页上添加总页数?

    10 回复  |  直到 9 年前
        1
  •  11
  •   Dave Jarvis James Eichele    10 年前
    1. 处理来自 PdfWriter 到A bytestream 首先是一个伪页计数。
    2. 创建一个 PdfReader 从那 旁通流 呼唤 PdfReader.getNumberOfPages 以获取实际的页面计数。
    3. 重新创建PDF输出,知道页数是多少,相应地更改页脚。

    这很混乱,但是如果没有两次通过的方法,就很难知道页数。见 example code 有关操作PDF的详细信息。

        2
  •  7
  •   Jack Ishu    14 年前

    可以创建继承自的类 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
    
        3
  •  5
  •   Dan J    14 年前

    不再搜索,这里是解决方案。如果他们删除了这个链接,我将把代码发布到我的站点并托管这个链接。

    iText page numbers example

        4
  •  3
  •   Milhous    15 年前

    这是我使用的代码。将页面写入输出不会增加太多开销。

    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();
    
        5
  •  2
  •   Chris Clarke    17 年前

    从一个快速的网络搜索中提醒自己;看一下

    Example

    相关方法是 onEndPage() 生成“X”和 onCloseDocument() 当您到达文档结尾时生成“Y”。

        6
  •  1
  •   Pinch    12 年前

    这是一个方便的功能!(基于Milhous的方法)(使用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();
            }
    
        7
  •  0
  •   Santhosh    12 年前

    尝试这个,因为我也遭受了这个痛苦,我也新建了这个库,所以在很多麻烦之后,我得到的结果只是尝试应用逻辑两次,正如我在评论中提到的。

    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);
        }
    }
    
        8
  •  0
  •   deldev    11 年前

    这是您的代码片段:

    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/ . 非常感谢,722

        9
  •  0
  •   Integrating Stuff    10 年前

    如其他答案所示,您首先需要创建PDF,然后查看您创建的PDF包含的页面数,然后将页脚添加到每个页面。 理想的处理方法是pdfstamper,它的目的是向现有的pdf/existing pdf页面添加额外的元素。

    下面是一个基于milhous示例的详细示例:

    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();
    
        10
  •  0
  •   AxelH    10 年前

    这是在Java中转换的RAMA代码(至少部分)

    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();
        }
    
    }
    
    推荐文章