C# Itextsharp:在一个页面上调整2个元素
因此,我在使用C#(.NET4.0+WinForms)和iTextSharp 5.1.2时遇到了这个问题 我有一些扫描图像存储在数据库中,需要用这些图像动态生成PDF。有些文件只有一页,而其他文件只有几百页。使用以下工具可以很好地工作:C# Itextsharp:在一个页面上调整2个元素,c#,image,pdf,itextsharp,C#,Image,Pdf,Itextsharp,因此,我在使用C#(.NET4.0+WinForms)和iTextSharp 5.1.2时遇到了这个问题 我有一些扫描图像存储在数据库中,需要用这些图像动态生成PDF。有些文件只有一页,而其他文件只有几百页。使用以下工具可以很好地工作: foreach (var page in pages) { Image pageImage = Image.GetInstance(page.Image); pageImage.ScaleToFit(documen
foreach (var page in pages)
{
Image pageImage = Image.GetInstance(page.Image);
pageImage.ScaleToFit(document.PageSize.Width,document.PageSize.Height);
pageImage.Alignment = Image.ALIGN_TOP | Image.ALIGN_CENTER;
document.Add(pageImage);
document.NewPage();
//...
}
问题是:
我需要在最后一页的底部添加一个小表格
我尝试:
foreach (var page in pages)
{
Image pageImage = Image.GetInstance(page.Image);
pageImage.ScaleToFit(document.PageSize.Width,document.PageSize.Height);
pageImage.Alignment = Image.ALIGN_TOP | Image.ALIGN_CENTER;
document.Add(pageImage);
document.NewPage();
//...
}
Table t = new table....
document.Add(t);
该表已成功添加,但如果图像的大小与文档的页面大小相匹配,则该表将添加到下一页
我需要调整文档最后一个图像的大小(如果它有多个图像,或者第一个图像只有1个),以便将表直接放在该页面上(带有图像),并且两个图像都只显示一个页面
我尝试按百分比缩放图像,但考虑到最后一页上的图像大小未知,并且它必须填充页面的最大部分,我需要以友好的方式进行缩放
有什么想法吗?让我给你一些可能对你有帮助的东西,然后我会给你一个完整的工作示例,你应该能够自定义 第一件事是
PdfPTable
有一个名为WriteSelectedRows()
的特殊方法,允许您在精确的x,y
坐标处绘制表格。它有六个重载,但最常用的重载可能是:
PdfPTable.WriteSelectedRows(int rowStart,int rowEnd, float xPos, float yPos, PdfContentByte canvas)
要放置左上角位于400400
的表格,请调用:
t.WriteSelectedRows(0, t.Rows.Count, 400, 400, writer.DirectContent);
调用此方法之前,需要先使用SetTotalWidth()
设置表的宽度:
//Set these to your absolute column width(s), whatever they are.
t.SetTotalWidth(new float[] { 200, 300 });
第二件事是,在渲染整个表之前,表的高度是未知的。这意味着您无法确切地知道将桌子放在何处,使其真正位于底部。解决方法是首先将表呈现为临时文档,然后计算高度。以下是我用于执行此操作的方法:
public static float CalculatePdfPTableHeight(PdfPTable table)
{
using (MemoryStream ms = new MemoryStream())
{
using (Document doc = new Document(PageSize.TABLOID))
{
using (PdfWriter w = PdfWriter.GetInstance(doc, ms))
{
doc.Open();
table.WriteSelectedRows(0, table.Rows.Count, 0, 0, w.DirectContent);
doc.Close();
return table.TotalHeight;
}
}
}
}
这可以这样称呼:
PdfPTable t = new PdfPTable(2);
//In order to use WriteSelectedRows you need to set the width of the table
t.SetTotalWidth(new float[] { 200, 300 });
t.AddCell("Hello");
t.AddCell("World");
t.AddCell("Test");
t.AddCell("Test");
float tableHeight = CalculatePdfPTableHeight(t);
因此,这里有一个针对iTextSharp 5.1.1.0的完整WinForms示例(我知道你说的是5.1.2,但这应该是一样的)。此示例在桌面上名为“测试”的文件夹中查找所有JPEG。然后将它们添加到8.5英寸x11英寸的PDF中。然后在PDF的最后一页,或者如果只有一个JPEG开始,它会将PDF的高度扩展到我们要添加的表格的高度,然后将表格放在左下角。请参阅代码本身中的注释以了解更多解释
using System;
using System.Text;
using System.Windows.Forms;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.IO;
namespace Full_Profile1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public static float CalculatePdfPTableHeight(PdfPTable table)
{
//Create a temporary PDF to calculate the height
using (MemoryStream ms = new MemoryStream())
{
using (Document doc = new Document(PageSize.TABLOID))
{
using (PdfWriter w = PdfWriter.GetInstance(doc, ms))
{
doc.Open();
table.WriteSelectedRows(0, table.Rows.Count, 0, 0, w.DirectContent);
doc.Close();
return table.TotalHeight;
}
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
//Create our table
PdfPTable t = new PdfPTable(2);
//In order to use WriteSelectedRows you need to set the width of the table
t.SetTotalWidth(new float[] { 200, 300 });
t.AddCell("Hello");
t.AddCell("World");
t.AddCell("Test");
t.AddCell("Test");
//Calculate true height of the table so we can position it at the document's bottom
float tableHeight = CalculatePdfPTableHeight(t);
//Folder that we are working in
string workingFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Test");
//PDF that we are creating
string outputFile = Path.Combine(workingFolder, "Output.pdf");
//Get an array of all JPEGs in the folder
String[] AllImages = Directory.GetFiles(workingFolder, "*.jpg", SearchOption.TopDirectoryOnly);
//Standard iTextSharp PDF init
using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (Document document = new Document(PageSize.LETTER))
{
using (PdfWriter writer = PdfWriter.GetInstance(document, fs))
{
//Open our document for writing
document.Open();
//We do not want any margins in the document probably
document.SetMargins(0, 0, 0, 0);
//Declare here, init in loop below
iTextSharp.text.Image pageImage;
//Loop through each image
for (int i = 0; i < AllImages.Length; i++)
{
//If we only have one image or we are on the second to last one
if ((AllImages.Length == 1) | (i == (AllImages.Length - 1)))
{
//Increase the size of the page by the height of the table
document.SetPageSize(new iTextSharp.text.Rectangle(0, 0, document.PageSize.Width, document.PageSize.Height + tableHeight));
}
//Add a new page to the PDF
document.NewPage();
//Create our image instance
pageImage = iTextSharp.text.Image.GetInstance(AllImages[i]);
pageImage.ScaleToFit(document.PageSize.Width, document.PageSize.Height);
pageImage.Alignment = iTextSharp.text.Image.ALIGN_TOP | iTextSharp.text.Image.ALIGN_CENTER;
document.Add(pageImage);
//If we only have one image or we are on the second to last one
if ((AllImages.Length == 1) | (i == (AllImages.Length - 1)))
{
//Draw the table to the bottom left corner of the document
t.WriteSelectedRows(0, t.Rows.Count, 0, tableHeight, writer.DirectContent);
}
}
//Close document for writing
document.Close();
}
}
}
this.Close();
}
}
}
让我给你一些可能对你有帮助的东西,然后我会给你一个完整的工作示例,你应该能够自定义 第一件事是
PdfPTable
有一个名为WriteSelectedRows()
的特殊方法,允许您在精确的x,y
坐标处绘制表格。它有六个重载,但最常用的重载可能是:
PdfPTable.WriteSelectedRows(int rowStart,int rowEnd, float xPos, float yPos, PdfContentByte canvas)
要放置左上角位于400400
的表格,请调用:
t.WriteSelectedRows(0, t.Rows.Count, 400, 400, writer.DirectContent);
调用此方法之前,需要先使用SetTotalWidth()
设置表的宽度:
//Set these to your absolute column width(s), whatever they are.
t.SetTotalWidth(new float[] { 200, 300 });
第二件事是,在渲染整个表之前,表的高度是未知的。这意味着您无法确切地知道将桌子放在何处,使其真正位于底部。解决方法是首先将表呈现为临时文档,然后计算高度。以下是我用于执行此操作的方法:
public static float CalculatePdfPTableHeight(PdfPTable table)
{
using (MemoryStream ms = new MemoryStream())
{
using (Document doc = new Document(PageSize.TABLOID))
{
using (PdfWriter w = PdfWriter.GetInstance(doc, ms))
{
doc.Open();
table.WriteSelectedRows(0, table.Rows.Count, 0, 0, w.DirectContent);
doc.Close();
return table.TotalHeight;
}
}
}
}
这可以这样称呼:
PdfPTable t = new PdfPTable(2);
//In order to use WriteSelectedRows you need to set the width of the table
t.SetTotalWidth(new float[] { 200, 300 });
t.AddCell("Hello");
t.AddCell("World");
t.AddCell("Test");
t.AddCell("Test");
float tableHeight = CalculatePdfPTableHeight(t);
因此,这里有一个针对iTextSharp 5.1.1.0的完整WinForms示例(我知道你说的是5.1.2,但这应该是一样的)。此示例在桌面上名为“测试”的文件夹中查找所有JPEG。然后将它们添加到8.5英寸x11英寸的PDF中。然后在PDF的最后一页,或者如果只有一个JPEG开始,它会将PDF的高度扩展到我们要添加的表格的高度,然后将表格放在左下角。请参阅代码本身中的注释以了解更多解释
using System;
using System.Text;
using System.Windows.Forms;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.IO;
namespace Full_Profile1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public static float CalculatePdfPTableHeight(PdfPTable table)
{
//Create a temporary PDF to calculate the height
using (MemoryStream ms = new MemoryStream())
{
using (Document doc = new Document(PageSize.TABLOID))
{
using (PdfWriter w = PdfWriter.GetInstance(doc, ms))
{
doc.Open();
table.WriteSelectedRows(0, table.Rows.Count, 0, 0, w.DirectContent);
doc.Close();
return table.TotalHeight;
}
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
//Create our table
PdfPTable t = new PdfPTable(2);
//In order to use WriteSelectedRows you need to set the width of the table
t.SetTotalWidth(new float[] { 200, 300 });
t.AddCell("Hello");
t.AddCell("World");
t.AddCell("Test");
t.AddCell("Test");
//Calculate true height of the table so we can position it at the document's bottom
float tableHeight = CalculatePdfPTableHeight(t);
//Folder that we are working in
string workingFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Test");
//PDF that we are creating
string outputFile = Path.Combine(workingFolder, "Output.pdf");
//Get an array of all JPEGs in the folder
String[] AllImages = Directory.GetFiles(workingFolder, "*.jpg", SearchOption.TopDirectoryOnly);
//Standard iTextSharp PDF init
using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (Document document = new Document(PageSize.LETTER))
{
using (PdfWriter writer = PdfWriter.GetInstance(document, fs))
{
//Open our document for writing
document.Open();
//We do not want any margins in the document probably
document.SetMargins(0, 0, 0, 0);
//Declare here, init in loop below
iTextSharp.text.Image pageImage;
//Loop through each image
for (int i = 0; i < AllImages.Length; i++)
{
//If we only have one image or we are on the second to last one
if ((AllImages.Length == 1) | (i == (AllImages.Length - 1)))
{
//Increase the size of the page by the height of the table
document.SetPageSize(new iTextSharp.text.Rectangle(0, 0, document.PageSize.Width, document.PageSize.Height + tableHeight));
}
//Add a new page to the PDF
document.NewPage();
//Create our image instance
pageImage = iTextSharp.text.Image.GetInstance(AllImages[i]);
pageImage.ScaleToFit(document.PageSize.Width, document.PageSize.Height);
pageImage.Alignment = iTextSharp.text.Image.ALIGN_TOP | iTextSharp.text.Image.ALIGN_CENTER;
document.Add(pageImage);
//If we only have one image or we are on the second to last one
if ((AllImages.Length == 1) | (i == (AllImages.Length - 1)))
{
//Draw the table to the bottom left corner of the document
t.WriteSelectedRows(0, t.Rows.Count, 0, tableHeight, writer.DirectContent);
}
}
//Close document for writing
document.Close();
}
}
}
this.Close();
}
}
}
只需使用方法表。CalculateHeights()如果你想知道表的高度。只需使用方法表。CalculateHeights()如果你想知道表的高度。克里斯,首先感谢你的帮助。但是有一点误解(我的错)。我实际上不需要调整页面的大小,我需要调整图像的大小,这样具有已调整大小的图像的表就可以仅复制一个页面。我无法更改页面大小,因为有一个自动打印系统接收PDF文件,并始终使用A4纸打印:你能想象一种方法吗?@Randolf Rincón-Fadul,请参阅我的编辑above@RandolfRincón-Fadul,很高兴我能帮上忙!好主意。几个小时来,我一直把头撞在桌子上,试图计算出桌子的高度,然后再把它们写进文件。一个简单的“不要打断新页面”功能很难实现!克里斯,首先,谢谢你的帮助。但是有一点误解(我的错)。我实际上不需要调整页面的大小,我需要调整图像的大小,这样具有已调整大小的图像的表就可以仅复制一个页面。我无法更改页面大小,因为有一个自动打印系统接收PDF文件,并始终使用A4纸打印:你能想象一种方法吗?@Randolf Rincón-Fadul,请参阅我的编辑above@RandolfRincón-Fadul,很高兴我能帮上忙!好主意。几个小时来,我一直把头撞在桌子上,试图计算出桌子的高度,然后再把它们写进文件。一个简单的“不要打断新页面”功能很难实现!如果表未附加到文档,则返回0,这是没有帮助的。如果表未附加到文档,则返回0,这是没有帮助的。