Как добавить общий номер страницы на каждую страницу с помощью iText?
Как добавить общий номер страницы на каждую страницу с помощью iText?
Ответ 1
- Обработать вывод с
PdfWriter
доbytestream
сначала с помощью фиктивной страницы. - Создайте
PdfReader
из этогоbytestream
, вызвавPdfReader.getNumberOfPages
, чтобы получить фактический счет страницы. - Создайте PDF-выход, зная, что такое счетчик страниц, соответственно изменив нижний колонтитул.
Это беспорядочно, но нет простого способа узнать количество страниц без двухпроходного подхода. Подробнее об управлении PDF файлами см. пример кода.
Ответ 2
Вы можете создать класс, наследующий от 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
Больше не искать, вот решение. Если они удалят эту ссылку, я отправлю код на свой сайт и разместим ссылку.
Ответ 4
Из быстрого веб-поиска, чтобы напомнить себе об этом; взгляните на
Соответствующие методы onEndPage()
для создания "X" и onCloseDocument()
для создания "Y" после того, как вы нажмете на конец документа.
Ответ 5
Вот код, который я использовал. Это не добавляет больших накладных расходов для записи страниц на выход.
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();
Ответ 6
Вот удобная функция! (На основе подхода Milhous) (это использует его версию 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
Попробуйте это, потому что я тоже страдал от этого, и я также стал новой этой библиотекой, поэтому после многих неприятностей я получил результат, просто попытаюсь применить логику дважды, как я упомянул в комментариях.
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 variable using this logic.
and second time servlet 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
Это фрагмент кода:
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
Ответ 9
Как указывают другие ответы, вам сначала нужно создать pdf файл, затем посмотреть, сколько страниц содержит файл pdf, а затем добавить нижний колонтитул на каждую страницу. Идеальный класс для этого - PdfStamper, целью которого является добавление дополнительных элементов в существующие pdf/существующие 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
Это код Rama, преобразованный в 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();
}
}