我正在使用ASP MVC,我使用iTextSharp在我的应用程序中生成PDF。但现在我有一个问题:我打印列表,当存在多个页面时,我想显示页码(例如:Page 1 to 4
)。我找到了一些例子,但我认为它比我需要做的更复杂(比如exameple)。
修改 我找到了example 2。我可以计算页数,但我不能在页面中打印数字。
我做了什么:
public ActionResult downloadListaISCC(DateTime? DataFimFiltro)
{
//Code to generate list to PDF
//My document
Document doc1 = new Document();
doc1.SetPageSize(iTextSharp.text.PageSize.A4);
doc1.SetMargins(0f, 0f, 0f, 0f);
doc1.NewPage();
MemoryStream pdfStream = new MemoryStream();
PdfWriter pdfWriter = PdfWriter.GetInstance(doc1, pdfStream);
//Code to create table
doc1.Add(table); //table list in document
//Follow the example 2 (link)
pdfWriter.CloseStream = true;
doc1.Close();
//E fui seguindo o exemplo do segundo link
string file = "D:/gerarPDFOleotorres/"+ nomeDoc +"";
// add page numbers
Document copyDoc = new Document();
PdfCopy copyPdf = new PdfCopy(copyDoc, new FileStream(file, FileMode.Create));
copyPdf.SetPageSize(PageSize.A4.Rotate());
copyDoc.Open();
// read the initial pdf document
PdfReader reader = new PdfReader(pdfStream.ToArray());
int totalPages = reader.NumberOfPages;
PdfImportedPage copiedPage = null;
iTextSharp.text.pdf.PdfCopy.PageStamp stamper = null;
for (int i = 0; i < totalPages; i++)
{
// get the page and create a stamper for that page
copiedPage = copyPdf.GetImportedPage(reader, (i + 1));
stamper = copyPdf.CreatePageStamp(copiedPage);
// add a page number to the page
ColumnText.ShowTextAligned(stamper.GetUnderContent(), Element.ALIGN_CENTER, new Phrase((i + 1) + "/" + totalPages, fontetexto), 820f, 15, 0);
stamper.AlterContents();
// add the altered page to the new document
copyPdf.AddPage(copiedPage);
}
copyDoc.Close();
reader.Close();
// flush and clear the document from memory
pdfStream.Flush();
pdfStream.Close();
}
答案 0 :(得分:11)
基本上,您有两种选择:要么一次创建文档,要么两次创建文档。
如果您一次创建文档,您事先不知道Y的值(总页数),因此您需要创建一个PdfTemplate
对象作为占位符。这在MovieCountries1示例中进行了演示。
在此示例中,我们创建了一个扩展TableHeader
的{{1}}类。我们在PdfPageEventHelper
方法中为PdfTemplate
创建total
类的实例,我们在OnOpenDocument()
方法中使用此total
占位符,我们在其中添加标题或页脚,我们用OnEndPage()
方法填写总页数。
这种方法的缺点是很难预测OnCloseDocument()
所需的尺寸。优点是您可以一次创建文档(您不需要先在内存中创建文档)。
如果您通过两次传递创建文档,则首先创建没有页眉/页脚的文档,然后检查文档以查找它包含的页数。然后使用total
将页码添加到每个页面。这显示在TwoPasses示例中。
这些例子来自我的书“iText in Action - Second Edition”。您可以从以下网址免费下载第6章:http://manning.com/lowagie2/samplechapter6.pdf
如果您对特定功能有疑问,请参阅[官方文档] [4]。
更新:我不明白为什么你更喜欢看非官方的例子。我给你的例子如下:
PdfStamper
但是出于某种原因,你用谷歌搜索了一个更复杂的例子(并且你需要的东西太过分了)。
只需将using (PdfStamper stamper = new PdfStamper(reader, ms2)) {
// Loop over the pages and add a header to each page
int n = reader.NumberOfPages;
for (int i = 1; i <= n; i++) {
// Add content
}
}
部分替换为:
// Add content
请注意,我在ColumnText.ShowTextAligned(stamper.GetUnderContent(), Element.ALIGN_CENTER, new Phrase((i + 1) + "/" + totalPages, fontetexto), 297f, 15f, 0);
方法中调整了x值。您正在创建一个A4大小的页面,这意味着您的页面宽度为595个用户单位。如果在位置x = 820处添加页码,则会添加页脚,但它将位于页面的可见区域之外。如果不知道每种方法的参数,请不要复制/粘贴代码。
答案 1 :(得分:0)
对于记录 - 我用这种方式
byte[] bytes = memoryStream.ToArray();
//Save pdf in the temporary location.
System.IO.File.WriteAllBytes(Server.MapPath("~/TempReports/") + lbReports.Text + "_JEA.pdf", bytes);
/*This is a page counter - it stamps the number of pages in the document.
It will read dynamically the 'document' that was just closed above [document.Close();] from the location,
then in memory will write the new content plus the one from [byte[] bytes = memoryStream.ToArray();]
Solution has been applied from: https://www.aspsnippets.com/Articles/iTextSharp-Add-Page-numbers-to-existing-PDF-using-C-and-VBNet.aspx
*/
try
{
File.ReadAllBytes(Server.MapPath("~/TempReports/") + lbReports.Text + "_JEA.pdf");
iTextSharp.text.Font blackFont = FontFactory.GetFont("Arial", 7, iTextSharp.text.Font.BOLD, BaseColor.BLACK);
using (MemoryStream stream = new MemoryStream())
{
PdfReader reader = new PdfReader(bytes);
using (PdfStamper stamper = new PdfStamper(reader, stream))
{
int pages = reader.NumberOfPages;
for (int i = 1; i <= pages; i++)
{
ColumnText.ShowTextAligned(stamper.GetUnderContent(i),
@Element.ALIGN_LEFT, new Phrase(lbReports.Text + " - HD - JEA", blackFont), 63f, 24f, 0);
ColumnText.ShowTextAligned(stamper.GetUnderContent(i),
@Element.ALIGN_CENTER, new Phrase("Page " + i.ToString() + " of " + pages, blackFont), 300f, 24f, 0);
ColumnText.ShowTextAligned(stamper.GetUnderContent(i),
@Element.ALIGN_RIGHT, new Phrase("" + DateTime.Now, blackFont), 549f, 24f, 0);
}
txConnection.Text = "This report contains " + pages + " page(s)";
}
bytes = stream.ToArray();
}//End of page counter
/*System.IO.File.WriteAllBytes will write all bytes to file again*/
System.IO.File.WriteAllBytes(Server.MapPath("~/TempReports/") + lbReports.Text + "_JEA.pdf", bytes);
// Temporary path that is used to display the pdf in the embed.
System.IO.File.WriteAllBytes(Server.MapPath("~/TempReports/ReportsEmbed/") + lbReports.Text + "_JEA.pdf", bytes);
/*this is what sends the PDF to the embed viewer object
The ltEmbed is what receives the plugin to dispplay the file*/
string embed = "<object data=\"{0}\" type=\"application/pdf\" width=\"698px\" height=\"450px\">";
embed += "If you are unable to view file, you can download it from <a href = \"{0}\">here</a>";
embed += " or download <a target = \"_blank\" href = \"http://get.adobe.com/reader/\">Adobe PDF Reader</a> to view it.";
embed += "</object>";
ltEmbed.Text = string.Format(embed, ("http://localhost:65423/TempReports/ReportsEmbed/") + lbReports.Text + "_JEA.pdf");
memoryStream.Close();
this.Context.ApplicationInstance.CompleteRequest();
}
catch (DocumentException exe)
{
txConnection.Text = "There has been an error generating the file. Please try again. Error: " + exe;
}