Itextsharp:在一页上调整 2 个元素

2023-12-14

所以,我在使用 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();
        //...
    }

问题是:

我需要在最后一页的底部添加一个小表格。

I try:

    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() first:

//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();
        }
    }
}

EDIT

以下是根据您的评论进行的编辑。我只是发布内容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);
                        }

                    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Itextsharp:在一页上调整 2 个元素 的相关文章

  • VLC 媒体播放器有 C# 界面吗? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否可以使用 C 控制台应用程序中的包装器从 VLC 播放中当前播放的文件中读取曲目统计信息 时间 标
  • 使用 ADAL v3 使用 ClientID 对 Dynamics 365 进行身份验证

    我正在尝试对我们的在线 Dynamics CRM 进行身份验证以使用可用的 API 我能找到的唯一关于执行此操作的官方文档是 https learn microsoft com en us dynamics365 customer enga
  • 是否可以使用 http url 作为 DirectShow .Net 中源过滤器的源位置?

    我正在使用 DirectShow Net 库创建一个过滤器图 该过滤器图通过使用 http 地址和 WM Asf Writer 来流式传输视频 然后 在网页上 我可以使用对象元素在 Windows Media Player 对象中呈现视频源
  • 如何使用 openSSL 函数验证 PEM 证书的密钥长度

    如何验证以这种方式生成的 PEM 证书的密钥长度 openssl genrsa des3 out server key 1024 openssl req new key server key out server csr cp server
  • C# 中的 Stack<> 实现

    我最近一直在实现递归目录搜索实现 并且使用堆栈来跟踪路径元素 当我使用 string Join 连接路径元素时 我发现它们被颠倒了 当我调试该方法时 我查看了堆栈 发现堆栈内部数组中的元素本身是相反的 即最近 Push 的元素位于内部数组的
  • 在 C++ 代码中转换字符串

    我正在学习 C 并开发一个项目来练习 但现在我想在代码中转换一个变量 字符串 就像这样 用户有一个包含 C 代码的文件 但我希望我的程序读取该文件并插入将其写入代码中 如下所示 include
  • 防止控制台应用程序中的内存工作集最小化?

    我想防止控制台应用程序中的内存工作集最小化 在Windows应用程序中 我可以这样做覆盖 SC MINIMIZE 消息 http support microsoft com kb 293215 en us fr 1 但是 如何在控制台应用程
  • 混合模型优先和代码优先

    我们使用模型优先方法创建了一个 Web 应用程序 一名新开发人员进入该项目 并使用代码优先方法 使用数据库文件 创建了一个新的自定义模型 这 这是代码第一个数据库上下文 namespace WVITDB DAL public class D
  • Makefile 和 .Mak 文件 + CodeBlocks 和 VStudio

    我对整个 makefile 概念有点陌生 所以我对此有一些疑问 我正在 Linux 中使用 CodeBlocks 创建一个项目 我使用一个名为 cbp2mak 的工具从 CodeBlocks 项目创建一个 make 文件 如果有人知道更好的
  • OpenGL:如何检查用户是否支持glGenBuffers()?

    我检查了文档 它说 OpenGL 版本必须至少为 1 5 才能制作glGenBuffers 工作 用户使用的是1 5版本但是函数调用会导致崩溃 这是文档中的错误 还是用户的驱动程序问题 我正在用这个glGenBuffers 对于VBO 我如
  • Unity手游触摸动作不扎实

    我的代码中有一种 错误 我只是找不到它发生的原因以及如何修复它 我是统一的初学者 甚至是统一的手机游戏的初学者 我使用触摸让玩家从一侧移动到另一侧 但问题是我希望玩家在手指从一侧滑动到另一侧时能够平滑移动 但我的代码还会将玩家移动到您点击的
  • Linux 上的 RTLD_LOCAL 和dynamic_cast

    我们有一个由应用程序中的一些共享库构成的插件 我们需要在应用程序运行时更新它 出于性能原因 我们在卸载旧插件之前加载并开始使用新插件 并且只有当所有线程都使用旧插件完成后 我们才卸载它 由于新插件和旧插件的库具有相同的符号 我们dlopen
  • 对于 C# Express 用户来说,有哪些好的工具可以识别可能重复的代码? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 也可以看看 有什么工具可以检查重复的 VB NET 代码吗 https stackoverflow c
  • 如何从 Boost.PropertyTree 复制子树

    我有一些boost property tree ptree 我需要树来删除一些具有特定标签名称的元素 例如 xml 表示源ptree如下
  • Xamarin Forms Binding - 访问父属性

    我无法访问页面的 ViewModel 属性以便将其绑定到 IsVisible 属性 如果我不设置 BindingContext 我只能绑定它 有没有办法可以在设置 BindingContext 的同时访问页面的 viewmodel root
  • C++ 指针引用混淆

    struct leaf int data leaf l leaf r struct leaf p void tree findparent int n int found leaf parent 这是 BST 的一段代码 我想问一下 为什么
  • 如何在C#中控制datagridview光标移动

    我希望 datagridview 光标向右移动到下一列 而不是在向单元格输入数据后移动到下一行 我试图通过 dataGridView1 KeyDown 事件捕获键来控制光标 但这并不能阻止光标在将数据输入到单元格后移动到下一行 提前感谢你的
  • 构建 C# MVC 5 站点时项目之间的处理器架构不匹配

    我收到的错误如下 2017 年 4 月 20 日构建 13 23 38 C Windows Microsoft NET Framework v4 0 30319 Microsoft Common targets 1605 5 警告 MSB3
  • 如果将变量设置为等于新对象,旧对象会发生什么?

    假设我们有一个 X 类not有一个超载的operator 功能 class X int n X n 0 X int n n n int main X a 1 an object gets constructed here more code
  • 从后面的代码添加外部 css 文件

    我有一个 CSS 文件 例如 SomeStyle css 我是否可以将此样式表文档从其代码隐藏应用到 aspx 页面 您可以将文字控件添加到标头控件中 Page Header Controls Add new System Web UI L

随机推荐

  • Javascript从亚马逊s3存储桶下载文件?

    我试图从 Amazon S3 上的存储桶下载文件 我想知道是否可以编写一个 JavaScript 来从存储桶下载这样的文件 我在谷歌上搜索 但找不到任何可以帮助我做到这一点的资源 需要考虑的一些步骤是 对 Amazon S3 进行身份验证
  • 如何从命令行检查特定的 Subversion 修订版?

    我想签出文件夹的特定版本颠覆使用命令行 我没有看到用于指定修订号的选项TortoiseProc exe TortoiseProc exe command checkout
  • 如何更改 Android 中的代理设置(尤其是 Chrome)[关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 您能帮我一下吗 是否可以在 Android 中设置代理设置 尤其是在 Chrome 中 我在测试期间必须更改 Android 上的 IP 或者有什么软件可以帮助我解决这个问题 找到了
  • 如何连接mysql和Basex?

    我有一个使用 Mysql 作为数据库的应用程序 它使用了大量的 XML HTML 我想在 BaseX 中处理 mysql 数据并通过它更新数据库 有没有简单的方法连接数据库 我检查了http docs basex org wiki SQL但
  • HTTP.sys 请求队列和 IIS 应用程序池之间的关系

    我从中读到了这篇文章 HTTP sys 为每个工作进程维护一个请求队列 它将 HTTP 请求发送到工作进程的请求队列 该工作进程为所请求的应用程序所在的应用程序池提供服务 对于每个应用程序 HTTP sys 维护具有一个条目的 URI 命名
  • Javascript读取大文件失败

    JSON 文件大小为 6 GB 当用下面的代码读取时 var fs require fs var contents fs readFileSync large file txt toString 它有以下错误 buffer js 182 t
  • 如何用新行显示阅读提示

    我在用着read内置来读取变量 但我想让输入出现在下一行 即提示符输出一个新行 但两者都不起作用 read p Please input n name Please input n read p Please input n name Pl
  • java:如何使用 .txt 中的数据创建多个数组

    所以这是我必须编写的第一个真正的java程序 我对java也很陌生 该程序必须使用 2 个命令行参数运行 这些参数假定为 x 和 y 坐标 然后确定坐标所在的市和县 为此 我想使用 绕数 但是在开始程序的这些部分之前 我首先需要创建并填充不
  • 如何在 solr4 中对存储在其他服务器上的 XML 文件建立索引

    我将所有 XML 文件存储到另一台服务器上 并且我已在不同服务器上安装和配置 SOLR 我如何将这些 XML 文件索引到 SOLR 我已经检查过 nutch 但它的主要目的是抓取 html 页面并为其建立索引 我不需要爬行 我将所有这些文件
  • 使用 dplyr 对多列求和时忽略 NA

    我正在对多列进行求和 其中一些列不适用 我在用 dplyr mutate 然后写出各列的算术和以获得总和 但这些列有 NA 我想将它们视为零 我能够让它与 rowSums 一起使用 见下文 但现在使用 mutate 使用 mutate 可以
  • 在使用 Python 的 matplotlib 制作动画期间,第一组(散点)绘图数据保留在图表上

    我正在尝试为图表上的一条线和 3 个散点制作动画 除了图表上的第一组散点没有被删除之外 一切似乎都正常 这是代码 您可以尝试将 n 设置为 1 2 或 3 import numpy as np from math import from p
  • 当前可用的最好的 Ajax 历史记录和书签插件 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 似乎每个 Ajax 历史记
  • 如何为 Apache-CXF JAX-WS 启用 Spring Security

    如何在 Apache CXF 上为 apache JAX WS 启用 Spring Security 网络上的示例包括 Jax RS 示例 但我不使用 Jax RS 我不想使用 cxf 的安全性 如何在我的代码中实现它 两种可能的方式 Pu
  • gitignore 没有扩展名的二进制文件

    如何在中忽略二进制文件git使用 gitignore file 例子 g hello c o hello hello 文件是一个二进制文件 能git忽略这个文件 Ignore all Unignore all with extensions
  • Excel VBA 强制关闭 IE

    我目前正在使用以下子程序在自动化后关闭我的 IE Public Sub CloseIE Dim Shell As Object Dim IE As Object Set Shell CreateObject Shell Applicatio
  • 运算符重载中的类数据封装(私有数据)

    下面是代码 代码 访问说明符适用于类级别 而不是实例级别 因此Rational类可以查看任何其他类的私有数据成员Rational实例 自从你的Rational operator 是一个成员函数 它可以访问它的私有数据Rational争论 注
  • jquery动态绑定.on()选择父母还是孩子?

    例如 dataTable tbody tr on click function alert this text dataTable tbody on click tr function alert this text on 将 tr 与单击
  • opengl:将原点更改为左上角

    我在将 openGL 原点设置为视图的左上角时遇到问题 因此 在我的窗口调整大小处理程序中 我执行以下操作 ox and oy are some offsets and width and height are the required v
  • 有没有更好的方法来找出本地 git 分支是否存在?

    我正在使用以下命令来查明是否localgit 分支与branch name存在于我的存储库中 它是否正确 有没有更好的办法 请注意 我是在脚本内执行此操作 为此我想使用管道命令如果可能的话 git show ref verify quiet
  • Itextsharp:在一页上调整 2 个元素

    所以 我在使用 C NET 4 0 WinForms 和 iTextSharp 5 1 2 时遇到了这个问题 我在数据库中存储了一些扫描图像 需要使用这些图像即时构建 PDF 有些文件只有一页 而其他文件则有数百页 使用以下方法工作得很好