gpt4 book ai didi

c# - Itextsharp : Adjust 2 elements on exactly one page

转载 作者:太空宇宙 更新时间:2023-11-03 17:27:19 24 4
gpt4 key购买 nike

所以,我在使用 C#(.NET 4.0 + WinForms)和 iTextSharp 5.1.2 时遇到了这个问题。

我有一些扫描图像存储在数据库中,需要使用这些图像即时构建 PDF。有些文件只有一页,而另一些则有数百页。这工作得很好,使用:

    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);

表格已成功添加,但如果图像的大小适合文档的页面大小,则表格会添加到下一页。

我需要调整文档最后一张图片的大小(如果它有多个图片,或者如果只有一张图片则为第一个图片)以便将表格直接放在该页面上(带有图片)并且两个都只占用一页.

我尝试按百分比缩放图像,但考虑到将在最后一页上显示的图像的图像大小是未知的,并且它必须填充页面的最大部分,我需要以动态方式执行此操作。

有什么想法吗?

最佳答案

让我给你一些可能对你有帮助的东西,然后我会给你一个你应该能够自定义的完整的工作示例。

首先是 PdfPTable有一个特殊的方法叫做 WriteSelectedRows()这使您可以在精确的 x,y 处绘制表格协调。它有六个重载,但最常用的可能是:

PdfPTable.WriteSelectedRows(int rowStart,int rowEnd, float xPos, float yPos, PdfContentByte canvas)

放置一个左上角位于400,400的表格你会调用:

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,但这应该可以正常工作)。此示例在桌面上名为“Test”的文件夹中查找所有 JPEG。然后将它们添加到 8.5"x11"PDF。然后在 PDF 的最后一页,或者如果在唯一的页面上只有 1 个 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();
}
}
}

编辑

以下是根据您的评论进行的编辑。我只发布 for 的内容循环,这是唯一改变的部分。调用ScaleToFit时你只需要拿tableHeight考虑在内。

                    //Loop through each image
for (int i = 0; i < AllImages.Length; i++)
{
//Add a new page to the PDF
document.NewPage();

//Create our image instance
pageImage = iTextSharp.text.Image.GetInstance(AllImages[i]);

//If we only have one image or we are on the second to last one
if ((AllImages.Length == 1) | (i == (AllImages.Length - 1)))
{
//Scale based on the height of document minus the table height
pageImage.ScaleToFit(document.PageSize.Width, document.PageSize.Height - tableHeight);
}
else
{
//Scale normally
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);
}

}

关于c# - Itextsharp : Adjust 2 elements on exactly one page,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7590071/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com