У меня есть шаблон PDF, который содержит данные формы, которые являются постоянной высотой. В соответствии с этими данными мне нужно добавить таблицу с динамической высотой. В этой таблице может быть только одна строка и одна строка, или она может содержать 1000 строк и/или 1-1000 строк.iTextSharp Таблица Span Pages с использованием Stamper
Это код, который у меня есть, который отлично работает, за исключением того, что таблица не будет переходить на новую страницу, если она большая.
private void InsertCurrentNeightborsOlder(string FileName)
{
//Create new PDF document
Document document = new Document(PageSize.LETTER, 20f, 20f, 0f, 20f);
iTextSharp.text.Font fntTableFontHdr = FontFactory.GetFont("Times New Roman", 8, iTextSharp.text.Font.BOLD, BaseColor.BLACK);
iTextSharp.text.Font fntTableFont = FontFactory.GetFont("Times New Roman", 8, iTextSharp.text.Font.NORMAL, BaseColor.BLACK);
try {
PdfWriter.GetInstance(document, new FileStream(FileName, FileMode.Create));
PdfPTable nTbl = new PdfPTable(5);
// Build the header
PdfPCell CellOneHdr = new PdfPCell(new Phrase("Name", fntTableFontHdr));
nTbl.AddCell(CellOneHdr);
PdfPCell CellTwoHdr = new PdfPCell(new Phrase("Address", fntTableFontHdr));
CellTwoHdr.HorizontalAlignment = Element.ALIGN_CENTER;
nTbl.AddCell(CellTwoHdr);
PdfPCell CellTreeHdr = new PdfPCell(new Phrase("Phone #", fntTableFontHdr));
CellTreeHdr.HorizontalAlignment = Element.ALIGN_CENTER;
nTbl.AddCell(CellTreeHdr);
PdfPCell CellFouHdr = new PdfPCell(new Phrase("Method", fntTableFontHdr));
CellFouHdr.HorizontalAlignment = Element.ALIGN_CENTER;
nTbl.AddCell(CellFouHdr);
PdfPCell CellFivHdr = new PdfPCell(new Phrase("Comments", fntTableFontHdr));
nTbl.AddCell(CellFivHdr);
//create column sizes
float[] rows = {
100f,
100f,
70f,
100f,
100f
};
//set row width
nTbl.SetTotalWidth(rows);
nTbl.CompleteRow();
// Add the Cells to the data table
if (ReportDataSet.Tables("CurrentNeighbors").Rows.Count > 0) {
foreach (DataRow r in ReportDataSet.Tables("CurrentNeighbors").Rows) {
nTbl.AddCell(new Paragraph(r("FullName").ToString, fntTableFont));
nTbl.AddCell(new Paragraph(r("Address").ToString, fntTableFont));
PdfPCell cell = new PdfPCell(new Paragraph(r("PhoneNumber").ToString, fntTableFont));
cell.HorizontalAlignment = 1;
nTbl.AddCell(cell);
// nTbl.AddCell(New Paragraph(r("PhoneNumber").ToString, fntTableFont))
nTbl.AddCell(new Paragraph(r("ContactMethod").ToString, fntTableFont));
nTbl.AddCell(new Paragraph(r("Comments").ToString, fntTableFont));
}
} else {
nTbl.AddCell(new Paragraph("Nothing Entered", fntTableFont));
nTbl.AddCell(new Paragraph(" ", fntTableFont));
nTbl.AddCell(new Paragraph(" ", fntTableFont));
nTbl.AddCell(new Paragraph(" ", fntTableFont));
nTbl.AddCell(new Paragraph(" ", fntTableFont));
}
document.Open();
nTbl.HeaderRows = 1;
nTbl.SplitLate = false;
document.Add(nTbl);
} catch (Exception ex) {
} finally {
document.Close();
}
}
«FileName» Параметр передается содержит местоположение исходного файла, который я хочу, чтобы добавить таблицу.
Возможно ли это сделать, и если да, то что мне не хватает?
EDIT:
Вот еще одна функция, которую я попробовал (с помощью Stamper). Может быть, я далеко на этом тоже, но это то, что я пытаюсь выяснить:
private void InsertCurrentNeightbors(string FileName)
{
// This is the Temporary File that we are working with. This file already has data in it
string oldFile = FileName;
// Create a new Temporary file that we can write to
string newFile = My.Computer.FileSystem.GetTempFileName();
iTextSharp.text.pdf.PdfReader reader = null;
iTextSharp.text.pdf.PdfStamper stamper = null;
iTextSharp.text.pdf.PdfContentByte cb = null;
iTextSharp.text.Rectangle rect = null;
int pageCount = 0;
try {
reader = new iTextSharp.text.pdf.PdfReader(oldFile);
rect = reader.GetPageSizeWithRotation(1);
stamper = new iTextSharp.text.pdf.PdfStamper(reader, new System.IO.FileStream(newFile, System.IO.FileMode.Create));
iTextSharp.text.Font fntTableFontHdr = FontFactory.GetFont("Times New Roman", 8, iTextSharp.text.Font.BOLD, BaseColor.BLACK);
iTextSharp.text.Font fntTableFont = FontFactory.GetFont("Times New Roman", 8, iTextSharp.text.Font.NORMAL, BaseColor.BLACK);
cb = stamper.GetOverContent(1);
dynamic ct = new ColumnText(cb);
ct.Canvas = stamper.GetOverContent(reader.NumberOfPages + 1);
ct.Alignment = Element.ALIGN_LEFT;
ct.SetSimpleColumn(70, 36, PageSize.A4.Width - 36, PageSize.A4.Height - 300);
PdfPTable nTbl = new PdfPTable(5);
// Build the header
PdfPCell CellOneHdr = new PdfPCell(new Phrase("Name", fntTableFontHdr));
nTbl.AddCell(CellOneHdr);
PdfPCell CellTwoHdr = new PdfPCell(new Phrase("Address", fntTableFontHdr));
CellTwoHdr.HorizontalAlignment = Element.ALIGN_CENTER;
nTbl.AddCell(CellTwoHdr);
PdfPCell CellTreeHdr = new PdfPCell(new Phrase("Phone #", fntTableFontHdr));
CellTreeHdr.HorizontalAlignment = Element.ALIGN_CENTER;
nTbl.AddCell(CellTreeHdr);
PdfPCell CellFouHdr = new PdfPCell(new Phrase("Method", fntTableFontHdr));
CellFouHdr.HorizontalAlignment = Element.ALIGN_CENTER;
nTbl.AddCell(CellFouHdr);
PdfPCell CellFivHdr = new PdfPCell(new Phrase("Comments", fntTableFontHdr));
nTbl.AddCell(CellFivHdr);
//create column sizes
float[] rows = {
100f,
100f,
70f,
100f,
100f
};
//set row width
nTbl.SetTotalWidth(rows);
nTbl.CompleteRow();
// Add the Cells to the data table
if (ReportDataSet.Tables("CurrentNeighbors").Rows.Count > 0) {
foreach (DataRow r in ReportDataSet.Tables("CurrentNeighbors").Rows) {
nTbl.AddCell(new Paragraph(r("FullName").ToString, fntTableFont));
nTbl.AddCell(new Paragraph(r("Address").ToString, fntTableFont));
nTbl.AddCell(new Paragraph(r("PhoneNumber").ToString, fntTableFont));
nTbl.AddCell(new Paragraph(r("ContactMethod").ToString, fntTableFont));
nTbl.AddCell(new Paragraph(r("Comments").ToString, fntTableFont));
}
} else {
nTbl.AddCell(new Paragraph("Nothing Entered", fntTableFont));
nTbl.AddCell(new Paragraph(" ", fntTableFont));
nTbl.AddCell(new Paragraph(" ", fntTableFont));
nTbl.AddCell(new Paragraph(" ", fntTableFont));
nTbl.AddCell(new Paragraph(" ", fntTableFont));
}
nTbl.SplitLate() = false;
nTbl.WriteSelectedRows(0, 25, 85, 490, stamper.GetOverContent(reader.NumberOfPages));
stamper.Close();
reader.Close();
ct.Go();
// Now that the new temp file has been written, we need to delete the old temp file
// and rename the new temp file to the old temp file name
// Delete Old Temp file
My.Computer.FileSystem.DeleteFile(FileName);
// Rename the new temp file to the old temp file
My.Computer.FileSystem.RenameFile(newFile, System.IO.Path.GetFileName(FileName));
} catch (Exception ex) {
throw ex;
}
}
Я попробовать по ссылке, которую вы предоставили, но он не работает, как ожидалось. Все, что я мог сделать, это повторить страницу источника 100 раз на целевую страницу. Я знаю, что все это было связано с моей интерпретации исходного кода и преобразование, но это то, что я получил:
private void manipulatePdf(string src, string dest)
{
try {
// Read the template file into the reader variable
PdfReader reader = new PdfReader(src);
// Get the page side of the template file
iTextSharp.text.Rectangle pagesize = reader.GetPageSize(1);
// Create a Stamper for the destination file
PdfStamper stamper = new PdfStamper(reader, new System.IO.FileStream(dest, System.IO.FileMode.Create));
// Create a new Paragraph
Paragraph p = new Paragraph();
// Add Text into the new paragraph
p.Add(new Chunk("Hello "));
p.Add(new Chunk("World"));
// Declare your AcroFields so we can get the last field's position
AcroFields form = stamper.AcroFields();
// Get the Last AcroField's Position
Rectangle rect = form.GetFieldPositions("MethodOfVerification")(0).position;
int status = 0;
PdfImportedPage newPage = null;
ColumnText column = new ColumnText(stamper.GetOverContent(1));
column.SetSimpleColumn(rect);
int pagecount = 1;
// Add's 100 Items
int i = 0;
while (i < 100) {
i += 1;
// Creates a new paragraph object
column.AddElement(new Paragraph("Hello " + i.ToString));
// Adds the paragraph object to the column
column.AddElement(p);
// Draw content of column
status = column.Go();
if (ColumnText.HasMoreText(status)) {
// Creates a new page and stamps the Source PDF into the Destination PDF
newPage = loadPage(newPage, reader, stamper);
triggerNewPage(stamper, pagesize, newPage, column, rect, System.Threading.Interlocked.Increment(pagecount));
}
}
stamper.FormFlattening = true;
stamper.Close();
reader.Close();
} catch (Exception ex) {
}
}
public PdfImportedPage loadPage(PdfImportedPage page, PdfReader reader, PdfStamper stamper)
{
if (page == null) {
return stamper.GetImportedPage(reader, 1);
}
return page;
}
public void triggerNewPage(PdfStamper stamper, Rectangle pagesize, PdfImportedPage page, ColumnText column, Rectangle rect, int pagecount)
{
stamper.InsertPage(pagecount, pagesize);
PdfContentByte canvas = stamper.GetOverContent(pagecount);
canvas.AddTemplate(page, 0, 0);
// column.setCanvas(canvas)
column.Canvas() = canvas;
column.SetSimpleColumn(rect);
column.Go();
}
Можете ли вы начать динамический рендеринг на новой странице или он должен немедленно забрать, когда другой остановился? –
Я хочу, чтобы он отображал, где остановился последний текст. Причина в том, что они связаны друг с другом. Я знаю, что легким ответом было бы динамическое создание первой части формы, но я надеюсь на более элегантный способ сделать это. Моя конечная цель - создать PDF-файл, который будет составлять в среднем 50 страниц. – Talsiter
Одним из решений, которые вы могли бы попробовать, если бы вы могли начать новую страницу, было бы также создать новый pdf-файл с данными, полученными от чтения другого, а затем объединить два документа. –