PdfReader from MemoryStream() - c#

Can anyone give me an example of how to get a PdfReader from a MemoryStream? I can see that the PdfReader class has a couple of methods which look like likely candidates (GetStreamBytes & GetStreamBytesRaw), however these seem to want iText-specific streams, mine is just a regular Byte[] or MemoryStream.
This is using C# and .NET 4.
iTextSharp.text.pdf.PdfReader rdr = iTextSharp.text.pdf.PdfReader.GetStreamBytesRaw

You can create a PdfReader from a MemoryStream, so long as the MemoryStream is a valid PDF object. If the MemoryStream is a valid PDF object, then one way to initiate the PdfReader is this way:
PdfReader _reader = new PdfReader((byte[])_memoryStream.ToArray());
In the code below, the PdfReader is initialized from .Net Resource which is returned as a byte[] when called from the Properties.Resources object, so the Resource and the MemoryStream are returning the same type to the PdfReader, a byte[]. I then create a PdfStamper object from the PdfReader object, and use a MemoryStream as the resulting container for the PdfStamper.
PdfReader _srcDoc = new PdfReader(Properties.Resources.Resource1);
MemoryStream _output = new MemoryStream();
PdfStamper _scratchDoc = new PdfStamper(_srcDoc, _output);

Maybe a bit late.
Try to set the streams position to 0.
...
stream.Flush(); // Don't know if this is necessary
stream.Position = 0;
PdfReader reader = new PdfReader(stream.ToArray());
...

If you want to just open the pdf in browser using bytes then do this :
public void ReturnPDF(byte[] contents, string attachmentFilename)
{
var response = HttpContext.Current.Response;
try
{
if (!string.IsNullOrEmpty(attachmentFilename))
{
response.ContentType = "application/pdf";
response.AddHeader("Content-Disposition", "attachment; filename=" + attachmentFilename);
}
response.ContentType = "application/pdf";
response.BinaryWrite(contents);
}
catch (Exception ex)
{
throw ex;
}
finally
{
response.End();
response.Flush();
response.Clear();
}
}

Related

itextsharp merging pdfs an emailing

I am battling with some memorystream logic.
I have a method that receives a list of Id. uses them to pull pdfs from a webserver, and merges them into one pdf.
I want to then email this pdf (working in memory only)
private Stream GetWebReport(string selected_id)
{
var IdLst = selected_id.Split(',').ToList();
MemoryStream stream = new MemoryStream();
Document document = new Document();
PdfCopy pdf = new PdfCopy(document, stream);
PdfReader reader = null;
try
{
document.Open();
foreach (var id in IdLst)
{
int i = Convert.ToInt32(id);
string invoice_url = string.Concat("http://specialurl/", id);
var urlpdf = new System.Net.WebClient().OpenRead(invoice_url);
reader = new PdfReader(urlpdf);
pdf.AddDocument(reader);
reader.Close();
}
}
catch (Exception)
{
throw;
}
finally
{
if (document != null)
{
document.Close();
}
}
return stream;
}
but when I try use the resulting stream for an email
var mem = GetWebReport(selected_id);
mem.Seek(0, SeekOrigin.Begin);
Attachment att = new Attachment(mem, "Report for you", "application/pdf");
I get told:
System.ObjectDisposedException: 'Cannot access a closed Stream.'
So I am sure that my itextsharp logic is good (When I use a filestream I get the correct results).
I am sure that my logic in passing streams is what is faulty
Use
PdfCopy pdf = new PdfCopy(document, stream);
pdf.CloseStream = false;
This will keep the stream open after closing the pdf to be used elsewhere.

how to return binary stream from iText pdf converter

Is it possible to return binary stream (byte[ ]) from pdfstamper ?
Basically the objective is to edit PDF doc and replace particular text.
Input already in binary stream (byte[ ])
I worked on C# environment & iText for the PDF editing lib.
Here's my piece of code :
PdfReader reader = new PdfReader(Mydoc.FileStream);
PdfDictionary dict = reader.GetPageN(1);
PdfObject pdfObject = dict.GetDirectObject(PdfName.CONTENTS);
if (pdfObject.IsStream())
{
PRStream stream = (PRStream)pdfObject;
byte[] data = PdfReader.GetStreamBytes(stream);
stream.SetData(System.Text.Encoding.ASCII.GetBytes(System.Text.Encoding.ASCII. GetString(data).Replace("[TextReplacement]", "Hello world")));
}
FileStream outStream = new FileStream(dest, FileMode.Create);
PdfStamper stamper = new PdfStamper(reader, outStream);
reader.Close();
return newPDFinStream // this result should be in stream byte[]
Understand that FileStream need to have output filepath like C:\location\new.pdf
is it possible to not temporary save it ? and directly return the binary?
Sure, just save it to a MemoryStream instead:
using (MemoryStream ms = new MemoryStream())
{
// Odd to have a constructor but not use the newly-created object.
// Smacks of the constructor doing too much.
var ignored = new PdfStamper(reader, ms);
return ms.ToArray();
}

how to save pdf file in client machine in mvc3?

I generate a pdf file on the fly and save it to the server side but i need to save it to the client machine. How to achieve this..
Document doc = new Document();
MemoryStream memoryStream = new MemoryStream();
string PDFName = ProjectName + ".pdf";
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(Server.MapPath("~/ProjectFiles") + "/" +
PDFName, FileMode.Create));
doc.Open();
//PDF Content
doc.Close();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=" + PDFName);
Response.Buffer = true;
Response.Clear();
Response.OutputStream.Write(memoryStream.GetBuffer(), 0, memoryStream.GetBuffer().Length);
Response.OutputStream.Flush();
Response.End();
In Response.OutputStream.Write(memoryStream.GetBuffer(), 0, memoryStream.GetBuffer().Length);
The memoryStream length is 0. I need to download the saved pdf into Cleint machine.
Please help me to fix this issue..
You are not writing anything to memoryStream.
Since you are generating PDFs on each request there is no need to save them to the file. You could generate the PDF to the MemoryStream directly.
MemoryStream memoryStream = new MemoryStream();
PdfWriter writer = PdfWriter.GetInstance(doc, memoryStream);
If your PDFs are not dynamic (eg. there is no need to generate them on every request) You can generate them to the file system as you do right now and then only read them from disk:
using (MemoryStream ms = new MemoryStream())
{
using (FileStream file = new FileStream(YourPdfFile, FileMode.Open, FileAccess.Read)) {
byte[] bytes = new byte[file.Length];
file.Read(bytes, 0, (int)file.Length);
ms.Write(bytes, 0, (int)file.Length);
}
}
But this makes sens only if the PDFs are generated once and then only served from disk.
EDIT: after writing into stream it was necessary to set memoryStream position to zero because it was at the end.
You have to affect memorystream like that :
PdfWriter pdfWriter = PdfWriter.GetInstance(document, memoryStream);

c# - DotNetZip open zip file from MemoryStream

What I like to do is instead of storing a zip file on disk, I like to open it up from a MemoryStream.
I am looking at the documentation for DotNetZip programming example:
Note that I tweaked it slightly based on what I thought may be needed.
var ms = new MemoryStream();
using (ZipFile zip = new ZipFile())
{
zip.AddFile("ReadMe.txt");
zip.AddFile("7440-N49th.png");
zip.AddFile("2008_Annual_Report.pdf");
zip.Save(ms); // this will save the files in memory steam
}
// now what I need is for the zip file to open up so that
the user can view all the files in it. Not sure what to do next after
zip.Save(ms) for this to happen.
Try this:
public ActionResult Index()
{
var memoryStream = new MemoryStream();
using (var zip = new ZipFile())
{
zip.AddFile("ReadMe.txt");
zip.AddFile("7440-N49th.png");
zip.AddFile("2008_Annual_Report.pdf");
zip.Save(memoryStream);
}
memoryStream.Seek(0, 0);
return File(memoryStream, "application/octet-stream", "archive.zip");
}
If this is local. you will need to save the stream in to the file and call Process.Start on it.
If this is on server. Just write your ms into Response with appropriate mime type.
You'd have to send the content of the memory stream back as the response:
using (MemoryStream ms = new MemoryStream())
{
using (ZipFile zip = new ZipFile())
{
zip.AddFile("ReadMe.txt");
zip.AddFile("7440-N49th.png");
zip.AddFile("2008_Annual_Report.pdf");
zip.Save(ms); // this will save the files in memory steam
}
context.Response.ContentType = "application/zip";
context.Response.AddHeader("Content-Length", ms.Size);
context.Response.AddHeader("Content-disposition", "attachment; filename=MyZipFile.zip");
ms.Seek(0, SeekOrigin.Begin);
ms.WriteTo(context.Response.OutputStream);
}
Try creating an ActionResult a bit like this:
I'm not 100% sure about the line var fileData = ms; and i don't have access to a dev environment just now, but there should be enough for you to work it out.
public ActionResult DownloadZip()
{
using (MemoryStream ms = new MemoryStream())
{
using (ZipFile zip = new ZipFile())
{
zip.AddFile("ReadMe.txt");
zip.AddFile("7440-N49th.png");
zip.AddFile("2008_Annual_Report.pdf");
zip.Save(ms); // this will save the files in memory steam
}
byte[] fileData = ms.GetBuffer();// I think this will work. Last time I did it, I did something like this instead... Zip.CreateZip("LogPosts.csv", System.Text.Encoding.UTF8.GetBytes(csv));
var cd = new System.Net.Mime.ContentDisposition
{
FileName = "Whatever.zip",
// always prompt the user for downloading, set to true if you want
// the browser to try to show the file inline
Inline = false,
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(fileData, "application/octet-stream");
}
}
this way we can write zip to output stream. may help
ZipFile zip = new ZipFile();
List<Attachment> listattachments = email.Attachments;
int acount = attachments.Count;
for (int i = 0; i < acount; i++)
{
zip.AddEntry(attachments[i].FileName, listattachments[i].Content);
}
Response.Clear();
Response.BufferOutput = false;
string zipName = String.Format("{0}.zip", message.Headers.From.DisplayName);
Response.ContentType = "application/zip";
Response.AddHeader("content-disposition", "attachment; filename=" + zipName);
zip.Save(Response.OutputStream);
Response.End();

How to convert pdf Byte[] Array to downloadable file using iTextSharp

Hei guys I have this byte array i want to convert to pdf and make it available for download. Anybody has any idea how this is done?
here is my Action Controller
public ActionResult DownloadLabTestResult(string labTestResultID)
{
PdfReader pdfReader = new PdfReader("Xue_Tang.pdf");
MemoryStream stream = new MemoryStream();
PdfStamper stamper = new PdfStamper(pdfReader, stream);
pdfReader.Close();
stamper.Close();
stream.Flush();
stream.Close();
byte[] pdfByte = stream.ToArray();
// So i got the byte array of the original pdf at this point. Now how do i convert this
// byte array to a downloadable pdf? i tried the method below but to no avail.
MemoryStream ms = new MemoryStream(pdfByte);
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=labtest.pdf");
Response.Buffer = true;
Response.Clear();
Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
Response.OutputStream.Flush();
Response.End();
return new FileStreamResult(Response.OutputStream, "application/pdf");
}
I am using similar code with a few differences:
Response.Clear();
MemoryStream ms = new MemoryStream(pdfByte);
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=labtest.pdf");
Response.Buffer = true;
ms.WriteTo(Response.OutputStream);
Response.End();
Call Reponse.Clear() earlier.
Use MemoryStream.WriteTo to write to Response.OutputStream.
Edit: sorry, I didn't see that you are using ASP.NET MVC, the above code is in a WebForms aspx page.
For ASP.NET MVC, couldn't you just do
return new FileStreamResult(ms, "application/pdf");
?

Categories