gpt4 book ai didi

itextsharp - 从itextsharp中的模板创建pdf并作为内容处置输出。

转载 作者:行者123 更新时间:2023-12-04 05:08:28 28 4
gpt4 key购买 nike

我想打开一个现有的pdf,添加一些文本,然后使用itext sharp作为内容配置输出。我有以下代码。它落在哪里是我想作为内存流输出,但需要filestream打开原始文件。

这就是我所拥有的。显然两次定义PdfWriter是行不通的。

   public static void Create(string path)
{
var Response = HttpContext.Current.Response;
Response.Clear();
Response.ContentType = "application/pdf";
System.IO.MemoryStream m = new System.IO.MemoryStream();
Document document = new Document();
PdfWriter wri = PdfWriter.GetInstance(document, new FileStream(path, FileMode.Create));
PdfWriter.GetInstance(document, m);
document.Open();
document.Add(new Paragraph(DateTime.Now.ToString()));
document.NewPage();
document.Add(new Paragraph("Hello World"));
document.Close();
Response.OutputStream.Write(m.GetBuffer(), 0, m.GetBuffer().Length);
Response.OutputStream.Flush();
Response.OutputStream.Close();
Response.End();
}

最佳答案

您遇到了一些问题,我将尽力帮助您解决。

首先,Document对象仅用于处理新的PDF,而不能修改现有的PDF。基本上,Document对象是一堆包装器类,这些包装器类抽象了PDF规范的基础部分,并允许您处理更高级的内容,例如段落和可重排的内容。这些抽象将您对“段落”的想法变成原始命令,这些命令一次将段落写成一行,而各行之间没有任何关系。使用现有文档时,没有安全的方法说明如何重排文本,因此不使用这些抽象。

相反,您想使用PdfStamper对象。使用此对象时,对于如何处理可能重叠的内容,您有两种选择,要么将新文本写在现有内容的顶部,要么将文本写在现有内容的顶部。实例化的GetOverContent()对象的两种方法GetUnderContent()PdfStamper将返回一个PdfContentByte对象,您可以使用该对象编写文本。

手动或通过ColumnText对象编写文本有两种主要方法。如果您已经完成HTML,则可以将ColumnText对象视为使用固定位置较大的单行,单列<TABLE>ColumnText的优点是您可以使用更高层次的抽象,例如Paragraph

以下是针对iTextSharp 5.1.2.0的完整工作的C#2010 WinForms应用程序,该应用程序展示了上述内容。如有任何疑问,请参见代码注释。将其转换为ASP.Net应该很容易。

using System;
using System.IO;
using System.Windows.Forms;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace WindowsFormsApplication1 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e) {
string existingFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "file1.pdf");
string newFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "file2.pdf");
using (FileStream fs = new FileStream(existingFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
using (Document doc = new Document(PageSize.LETTER)) {
using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) {
doc.Open();

doc.Add(new Paragraph("This is a test"));

doc.Close();
}
}
}

//Bind a PdfReader to our first document
PdfReader reader = new PdfReader(existingFile);
//Create a new stream for our output file (this could be a MemoryStream, too)
using (FileStream fs = new FileStream(newFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
//Use a PdfStamper to bind our source file with our output file
using (PdfStamper stamper = new PdfStamper(reader, fs)) {

//In case of conflict we want our new text to be written "on top" of any existing content
//Get the "Over" state for page 1
PdfContentByte cb = stamper.GetOverContent(1);

//Begin text command
cb.BeginText();
//Set the font information
cb.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1250, false), 16f);
//Position the cursor for drawing
cb.MoveText(50, 50);
//Write some text
cb.ShowText("This was added manually");
//End text command
cb.EndText();

//Create a new ColumnText object to write to
ColumnText ct = new ColumnText(cb);
//Create a single column who's lower left corner is at 100x100 and upper right is at 500x200
ct.SetSimpleColumn(100,100,500,200);
//Add a higher level object
ct.AddElement(new Paragraph("This was added using ColumnText"));
//Flush the text buffer
ct.Go();

}
}

this.Close();
}
}
}

至于关于 FileStreamMemoryStream的第二个问题,如果您查看iTextSharp中几乎所有方法(实际上据我所知)的方法签名,您会发现它们都采用 Stream对象,而不仅仅是 FileStream对象。每当您看到此内容时,即使在iTextSharp之外,这都意味着您可以传入 Stream的任何子类(包括 MemoryStream对象),其他所有内容均保持不变。

下面的代码是上面代码的略微修改版本。我删除了大部分评论以使其更简短。主要的变化是我们使用的是 MemoryStream而不是 FileStream。同样,当我们处理完PDF时,需要在访问原始二进制数据之前关闭 PdfStamper对象。 ( using语句稍后会为我们自动执行此操作,但它也会关闭流,因此我们需要在此处手动执行此操作。)

从来没有使用过 GetBuffer()MemoryStream方法。听起来像您想要的(我也错误地使用了它),但是您想要使用 ToArray()GetBuffer()包含未初始化的字节,通常会产生损坏的PDF。另外,我没有写HTTP响应流,而是先将字节保存到数组中。从调试的角度来看,这使我可以完成所有iTextSharp和 System.IO的代码,并确保它是正确的,然后对原始字节数组进行任何操作。就我而言,我没有网络服务器,因此我将它们写入磁盘,但是您可以轻松地调用 Response.BinaryWrite(bytes)
string existingFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "file1.pdf");
string newFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "file2.pdf");
PdfReader reader = new PdfReader(existingFile);
byte[] bytes;
using(MemoryStream ms = new MemoryStream()){
using (PdfStamper stamper = new PdfStamper(reader, ms)) {
PdfContentByte cb = stamper.GetOverContent(1);
ColumnText ct = new ColumnText(cb);
ct.SetSimpleColumn(100,100,500,200);
ct.AddElement(new Paragraph("This was added using ColumnText"));
ct.Go();

//Flush the PdfStamper's buffer
stamper.Close();
//Get the raw bytes of the PDF
bytes = ms.ToArray();
}
}

//Do whatever you want with the bytes
//Below I'm writing them to disk but you could also write them to the output buffer, too
using (FileStream fs = new FileStream(newFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
fs.Write(bytes, 0, bytes.Length);
}

关于itextsharp - 从itextsharp中的模板创建pdf并作为内容处置输出。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9468878/

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