iTextSharp 7 - Save Dialog - asp.net

Can anyone tell me how can I create a pdf file using iTextSharp 7 and popup a save dialog instead of saving it to a specific disk location?
My test code is the following:
protected void btnPrint_OnClick(object sender, EventArgs e)
{
Document doc = new Document(PageSize.A4, 25f, 20f, 20f, 10f);
var output = new FileStream(Server.MapPath("MyFirstPDF.pdf"), FileMode.Create);
var writer = PdfWriter.GetInstance(doc, output);
doc.Open();
doc.Add(new Paragraph("test!"));
doc.Close();
}

The workaround I found is the following:
After creating the document:
string path = "C:\\...";
string fileName = "PdfFile.pdf";
FileInfo fileInfo = new FileInfo(path);
Byte[] FileBuffer = File.ReadAllBytes(fileInfo.FullName);
if (FileBuffer != null)
{
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
Response.AddHeader("content-length", FileBuffer.Length.ToString());
Response.BinaryWrite(FileBuffer);
Response.Flush();
//DELETE FILE AFTER DOWNLOAD
fileInfo.Delete();
Response.End();
}

Related

Unable to cast object of type 'system.string' to type 'system.Byte[]' when trying to download a file from database

I am trying to download a file from database but its giving me an error called Unable to cast object of type 'System.String' to type 'System.Byte[]' on the line : Response.AddHeader("Content-Length", bytes.ToString());
Please tell me how can I cast string to byte in my case, thank you in advance.
I have a column named SaleFileName from which I want to download a file.
Aspx code:
<asp:TemplateField HeaderText="RecieptName" SortExpression="RecieptName">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CommandName="Download" CommandArgument='<%# Bind("SaleName") %>' Text='<%# Bind("SaleName") %>' ></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
Code Behind File:
protected void gridContributions_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Download")
{
// make sure fileName contains only file name like 'test.pdf'
string FileName = Convert.ToString(e.CommandArgument);
// make sure filePath contains file path like 'Uploads/Scheme/test.pdf'
string FilePath = e.CommandArgument.ToString();
string connectionString = WebConfigurationManager.ConnectionStrings["ConnectionString2"].ConnectionString;
// SqlConnection con = new SqlConnection(connectionString);
// byte[] bytes;
//string ContentType;
using (SqlConnection con = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "selectSaleFileName from Contributions where SaleFileName = #SaleFileName";
cmd.Parameters.AddWithValue("#SaleFileName", FileName);
//d.CommandType = CommandType.StoredProcedure;
cmd.Connection = con;
con.Open();
using ( SqlDataReader sdr = cmd.ExecuteReader())
{
sdr.Read();
bytes = (byte[])sdr["SaleFileName"];
//byte data = System.Text.Encoding.Unicode.GetBytes(SaleFileName.ToString);
}
con.Close();
}
}
Response.Clear();
Response.Buffer = true;
// Read the original file from disk
FileStream myFileStream = new FileStream( FilePath ,FileMode.Open);
long FileSize = myFileStream.Length;
byte[] Buffer = new byte[Convert.ToInt32(FileSize)];
myFileStream.Read(Buffer, 0, Convert.ToInt32(FileSize));
myFileStream.Close();
// // Tell the browse stuff about the file
Response.AddHeader("Content-Length", bytes.ToString());
// Response.AddHeader("Content-Length", FileNam
//Response.AddHeader("Content-Disposition", "inline; filename=" & fileName.Replace(" ", "_"));
Response.AddHeader("Content-Disposition", "attachment; FileName=" + FileName + ";");
Response.TransmitFile(FileName);
Response.ContentType = "application/octet-stream";
// Send the data to the browser
Response.BinaryWrite(Buffer);
Response.End();
}
}
You can't cast byte[] to string (unless its textual data and you should encode the data using any encoding like unicode, ASCII)
anyway, the problem in the Content-Length on http header, it should be the length of the file
so replace this line:
Response.AddHeader("Content-Length", bytes.ToString());
with this:
Response.AddHeader("Content-Length", FileSize.ToString());
if the file is stored databaase you need to get it as byte array, the following code will help you:
private byte[] ReadFileFromDatabase(string FileName) {
string connectionString = WebConfigurationManager.ConnectionStrings["ConnectionString2"].ConnectionString;
byte[] bytes = null;
using (SqlConnection con = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "selectSaleFileName from Contributions where SaleFileName = #SaleFileName";
cmd.Parameters.AddWithValue("#SaleFileName", FileName);
cmd.Connection = con;
con.Open();
using ( SqlDataReader sdr = cmd.ExecuteReader())
{
if (sdr.Read() )
bytes = (byte[])sdr["SaleFileName"];
}
con.Close();
}
}
return bytes;
}
protected void gridContributions_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Download")
{
string FileName = Convert.ToString(e.CommandArgument);
byte[] bytes = ReadFileFromDatabase(FileName);
Response.Clear()
Response.ContentType = "application/octet-stream"
Response.AddHeader("Content-Disposition", "attachment; FileName=" + FileName + ";");
Response.BinaryWrite(bytes)
Response.End()
}
}
if your file is stored outside database:
public static void DownloadFile(string path, string contentType)
{
FileInfo file = new FileInfo(path);
if (file.Exists)
{
Response.Clear();
Response.ClearHeaders();
Response.ClearContent();
Response.AddHeader("Content-Type", contentType);
Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name);
Response.AddHeader("Content-Length", file.Length.ToString());
Response.Flush();
Response.TransmitFile(file.FullName);
Response.End();
}
}
call it as:
string fullPath = Server.MapPath(relativePath);
DownloadFile(fullPath , "application/octet-stream");

Add background watermark logo to PDF file

I have rendered my aspx page to pdf successfully using ITextSharp.
Now i want to add watermark logo in background off PDF file please help me out i have been stuck into this.
Following is my code for export to pdf
private void ShowPdf(string s)
{
Response.ClearContent();
Response.ClearHeaders();
Response.AddHeader("Content-Disposition", "inline;filename=" + s);
Response.ContentType = "application/pdf";
Response.WriteFile(s);
Response.Flush();
Response.Clear();
}
public void PrepareControlForPDF()
{
MemoryStream mem = new MemoryStream();
StreamWriter twr = new StreamWriter(mem);
HtmlTextWriter myWriter = new HtmlTextWriter(twr);
divApplicantDetails.RenderControl(myWriter);
myWriter.Flush();
// myWriter.Dispose();
StreamReader strmRdr = new StreamReader(mem);
strmRdr.BaseStream.Position = 0;
string pageContent = strmRdr.ReadToEnd();
//CreatePDFDocument(strmRdr);
//strmRdr.Dispose();
///mem.Dispose();
CreatePDFDocument(pageContent);
//writer.Write(pageContent);
}
public void CreatePDFDocument(string strHtml)
{
string filename = ""+System.DateTime.Now.Day+"AppLetter.pdf";
// if (System.IO.File.Exists(Server.MapPath("../Pdf") + "/" + filename))
// {
// System.IO.File.Delete(Server.MapPath("../Pdf") + "/" + filename);
// }
string strFileName = Server.MapPath("../Pdf") + "/" + filename;
Document document = new Document();
try
{
PdfWriter.GetInstance(document, new FileStream(strFileName, FileMode.Create));
StringReader se = new StringReader(strHtml);
MemoryStream ms = new MemoryStream();
ms.Write(System.Text.Encoding.ASCII.GetBytes(strHtml), 0, System.Text.Encoding.ASCII.GetBytes(strHtml).Length);
//ms.Position = 0;
StreamReader sr = new StreamReader(new MemoryStream(new System.Text.ASCIIEncoding().GetBytes(strHtml)));
sr.BaseStream.Position = 0;
HTMLWorker obj = new HTMLWorker(document);
document.Open();
obj.Parse(se);
}
finally
{
document.Close();
}
}
I think you can achieve by creating a new class and implementing the IPdfPageEvent interface... refer here

Getting error to generate pdf

protected void txt_btn_Click(object sender, EventArgs e)
{
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=TestResult.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
StringBuilder htmlText = new StringBuilder();
htmlText.Append("<table style='color:red;' border='1'><tr><th>createing pdf</th><tr><td> abcdef</td></tr></table>");
StringReader stringReader = new StringReader(htmlText.ToString());
Document doc = new Document(PageSize.A4);
List<iTextSharp.text.IElement> elements =
iTextSharp.text.html.simpleparser.HTMLWorker.ParseToList(stringReader, null);
doc.Open();
foreach (object item in elements)
{
doc.Add((IElement)item);
}
doc.Close();
// Response Output
PdfWriter.GetInstance(doc, Response.OutputStream);
doc.Open();
//doc.Close();
Response.Write("PDF is created");
}
}
I am try to create pdf file.But pdf is created only 0kb.Mean when i open this it's shw error that May be pdf damaged
I'm assuming that you are using iTextSharp library.
private void GeneratePDF()
{
try
{
string pdfPath = "~/PDF/File_1.pdf";
StringBuilder sb = new StringBuilder();
sb.Append("Name : chamara" + Environment.NewLine);
sb.Append("Address : sri lanaka" + Environment.NewLine);
sb.Append("Institute : SLIIT" + Environment.NewLine);
Document doc = new Document();
PdfWriter.GetInstance(doc, new FileStream(Server.MapPath(pdfPath), FileMode.Create));
doc.Open();
doc.Add(new Paragraph(sb.ToString()));
doc.Close();
}
catch (Exception ex)
{
throw ex;
}
}

Open Generated pdf file through code directly without saving it onto the disk

I use Sharepoint 2010 and I am developing a web part where on a button click event, a pdf file needs to be generated and opened directly. Should not be saving onto the disk.
I tried the below code
protected void Button1_OnClick(object sender, EventArgs e)
{
Document myDoc = new Document(PageSize.A4.Rotate());
try
{
PdfWriter.GetInstance(myDoc, new FileStream(#"C:\Directory\Test.pdf", FileMode.Create));
myDoc.Open();
myDoc.Add(new Paragraph("Hello World"));
}
catch (DocumentException ex)
{
Console.Error.WriteLine(ex.Message);
}
myDoc.Close();
}
I also tried the below code which also generates the file on the Server which I dont want.
Document document = new Document(PageSize.A4);
PdfWriter.GetInstance(document, new FileStream(HttpContext.Current.Server.MapPath("~/Test.pdf"), FileMode.Create));
document.Open();
var WelcomePara = new Paragraph("Hello World");
document.Add(WelcomePara);
document.Close();
This one creates the pdf file on the desktop, I need it to be opened in the pdf format.Can someone help me please.
Almost every time that something accepts a FileStream is actually really accepts a generic System.IO.Stream object which FileStream is a subclass of. This means that you can instead use its cousin System.IO.MemoryStream which is what you are looking for:
byte[] bytes;
using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) {
using (iTextSharp.text.Document doc = new iTextSharp.text.Document(iTextSharp.text.PageSize.A4.Rotate())) {
using (iTextSharp.text.pdf.PdfWriter w = iTextSharp.text.pdf.PdfWriter.GetInstance(doc, ms)) {
doc.Open();
doc.NewPage();
doc.Add(new iTextSharp.text.Paragraph("Hello world"));
doc.Close();
bytes = ms.ToArray();
}
}
}
//Do whatever you want with the byte array here
You don't have to create the byte array if you don't want, I was just showing how to create a PDF and give you something ".net-like" for you to work with.
I was able to get it work finally.
using (var ms = new MemoryStream())
{
using (var document = new Document(PageSize.A4,50,50,15,15))
{
PdfWriter.GetInstance(document, ms);
document.Open();
document.Add(new Paragraph("HelloWorld"));
document.Close();
}
Response.Clear();
//Response.ContentType = "application/pdf";
Response.ContentType = "application/octet-stream";
Response.AddHeader("content-disposition", "attachment;filename= Test.pdf");
Response.Buffer = true;
Response.Clear();
var bytes = ms.ToArray();
Response.OutputStream.Write(bytes, 0, bytes.Length);
Response.OutputStream.Flush();
}
This Works for me.
using (var ms = new MemoryStream())
{
using (var document = new Document(PageSize.A4,50,50,15,15))
{
// step 2
PdfWriter writer = PdfWriter.GetInstance(document, ms);
// step 3
document.Open();
// XML Worker
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
p.Parse(new StringReader(--Your HTML--));
// step 5
document.Close();
}
Byte[] FileBuffer = ms.ToArray();
if (FileBuffer != null)
{
Response.ContentType = "application/pdf";
Response.AddHeader("content-length", FileBuffer.Length.ToString());
Response.BinaryWrite(FileBuffer);
}
}

Avoid saving new file on the disk

I am using ASP.NET 3.5 with iTextSharp and I have the following code:
var templatePath = Server.MapPath(#"~/Templates/template1.pdf");
var newFilePath = Server.MapPath(#"~/TempFiles/new.pdf");
PdfReader pdfReader = new PdfReader(templatePath);
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(newFilePath, FileMode.Create));
AcroFields pdfFormFields = pdfStamper.AcroFields;
pdfFormFields.SetField("Box1", "007");
pdfFormFields.SetField("Box2", "123456");
pdfStamper.FormFlattening = false;
pdfStamper.Close();
Response.ClearContent();
Response.Buffer = true;
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment;filename=new.pdf"));
Response.WriteFile(newFilePath);
Response.End();
The above code fills out a pdf file and saves the new file to the TempFiles folder. It then prompts the user to either save or open the file. Can I achieve the same functionality without saving the file to the TempFiles location?
Yes, you can write directly to the output stream of the response. I haven't used PdfStamper, but here's how I do it when generating new PDFs:
doc = new iTextSharp.text.Document(PageSize.A4);
writer = iTextSharp.text.pdf.PdfWriter.GetInstance(doc, Response.OutputStream);
writer.SetFullCompression();
doc.Open();
It looks like you pass a stream into the PdfStamper constructor, so the following should work:
var templatePath = Server.MapPath(#"~/Templates/template1.pdf");
PdfReader pdfReader = new PdfReader(templatePath);
Response.ClearContent();
Response.Buffer = true;
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment;filename=new.pdf"));
PdfStamper pdfStamper = new PdfStamper(pdfReader, Response.OutputStream);
AcroFields pdfFormFields = pdfStamper.AcroFields;
pdfFormFields.SetField("Box1", "007");
pdfFormFields.SetField("Box2", "123456");
pdfStamper.FormFlattening = false;
pdfStamper.Close();
Response.End();

Resources