Error while opening the excel file created by NPOI - c#

I am using NPOI to export the data to excel. I am forcing the file to be downloaded as an attachment for the user. When the user saves the file on the disk and opens the file it works but fails when he tries to select the open option from the download dialog box. Please see the code below. Not sure what is wrong
var xssfworkbook = new XSSFWorkbook();
var sheet1 = xssfworkbook.CreateSheet("Sheet 1");
//make header row
var row1 = sheet1.CreateRow(0);
var cell0 = row1.CreateCell(0);
cell0.SetCellValue("Firm Id");
var cell1 = row1.CreateCell(1);
cell1.SetCellValue("Account Number");
for (int i = 0; i < result.Count; i++)
{
var row = sheet1.CreateRow(i + 1);
if (result[i].FeeAmount != null)
{
var cellFirmID = row.CreateCell(0);
cellFirmID.SetCellValue(result[i].FirmID);
}
if (result[i].AccountNumber != null)
{
var cellAccountNumber = row.CreateCell(1);
cellAccountNumber.SetCellValue(result[i].AccountNumber);
}
}
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", "BESTINVEST_fee_rebate_loader_.xlsx"));
MemoryStream file = WriteToStream(xssfworkbook);
response.Clear();
response.BinaryWrite(file.ToArray());
response.End();
private MemoryStream WriteToStream(XSSFWorkbook xssfworkbook)
{
MemoryStream file = new MemoryStream();
xssfworkbook.Write(file);
return file;
}

This problem is from "culture". before Create excel:
var culture=new CultureInfo("en-US");
Thread.CurrentThread.CurrentCulture=culture;
Thread.CurrentThread.CurrentUICulture=culture;

I would recommend you make sure your cells are unlocked.
I use the following without problems:
var workbook = new XSSFWorkbook();
var members = (obj as IEnumerable<MemberListViewModel>).ToDataSourceResult(request).Data;
var sheet = workbook.CreateSheet(TempData["List"].ToString());
var headerRow = sheet.CreateRow(0);
headerRow.CreateCell(0).SetCellValue("Name");
headerRow.CreateCell(1).SetCellValue("Degrees");
headerRow.CreateCell(2).SetCellValue("Rank");
headerRow.CreateCell(3).SetCellValue("Endowed Professorship");
headerRow.CreateCell(4).SetCellValue("Department");
headerRow.CreateCell(5).SetCellValue("Program");
var font = workbook.CreateFont();
font.Boldweight = (short)NPOI.SS.UserModel.FontBoldWeight.Bold;
XSSFCellStyle style = (XSSFCellStyle)workbook.CreateCellStyle();
style.SetFont(font);
style.FillPattern = NPOI.SS.UserModel.FillPattern.SolidForeground;
style.FillForegroundColor = IndexedColors.Grey25Percent.Index;
style.IsLocked = false;
style.WrapText = true;
for (int i = 0; i < 6; i++)
{
var colStyle = sheet.GetColumnStyle(i);
colStyle.WrapText = !colStyle.WrapText;
sheet.SetDefaultColumnStyle(i, colStyle);
var cell = headerRow.Cells[i];
cell.CellStyle = style;
}
headerRow.RowStyle = style;
sheet.SetColumnWidth(0, 30 * 256);
sheet.SetColumnWidth(1, 20 * 256);
sheet.SetColumnWidth(2, 20 * 256);
sheet.SetColumnWidth(3, 50 * 256);
sheet.SetColumnWidth(4, 30 * 256);
sheet.SetColumnWidth(5, 50 * 256);
int rowNumber = 1;
style = (XSSFCellStyle)workbook.CreateCellStyle();
style.IsLocked = false;
style.WrapText = true;
foreach (MemberListViewModel member in members)
{
var row = sheet.CreateRow(rowNumber++);
row.CreateCell(0).SetCellValue(member.FullName);
row.CreateCell(1).SetCellValue(member.degrees);
row.CreateCell(2).SetCellValue(member.rank);
row.CreateCell(3).SetCellValue(member.endowed_professorship);
row.CreateCell(4).SetCellValue(member.department);
row.CreateCell(5).SetCellValue(member.program);
}
//var colStyle = sheet.GetColumnStyle(3);
//colStyle.WrapText = !colStyle.WrapText;
//sheet.SetDefaultColumnStyle(3, colStyle);
workbook.Write(output);
var fileName = String.Format(
"{0} {2} - {1}.xlsx",
DateTime.Now.ToString("yyyyMMdd-HHmmss"),
Utilities.getUsername(Utilities.GetCurrentUser()), TempData["List"]).Replace(":", "");
var file = File(output.ToArray(), Utilities.ExcelFileContentType, fileName);
var context = System.Web.HttpContext.Current;
context.Response.Clear();
context.Response.ClearContent();
context.Response.ClearHeaders();
context.Response.AddHeader("content-disposition", String.Format("inline;filename=\'{0}\'", fileName));
context.Response.ContentEncoding = System.Text.Encoding.UTF8;
context.Response.ContentType = file.ContentType;
context.Response.AddHeader("content-length", file.FileContents.Length.ToString());
context.Response.BinaryWrite(buffer: file.FileContents.ToArray());
context.Response.Flush();
context.Response.End();
output.Dispose();

Related

Get contents from each page in Crystal Report viewer and export it to a pdf

I need to get the content inside each page of a crystal report viewer and export it to a pdf file so that each page becomes a separate pdf and need to zip them.
Now i'm using DotNetZip dll for this.That's fine.
The issue is that i need to get contents of each page.Please Help..Below is few lines of code
Response.ContentType = "application/zip";
Response.AppendHeader("content-disposition", "attachment; filename=Reports.zip");
int i = 1;
int PageCount = report.FormatEngine.GetLastPageNumber(new
CrystalDecisions.Shared.ReportPageRequestContext());
if(PageCount >= 1){
using (ZipFile zip = new ZipFile())
{
for (i = 1; i <= PageCount; i++){
var re = report.ExportToStream(ExportFormatType.PortableDocFormat);
string Name = "Page" + i + ".pdf";
zip.AddEntry(Name, re);
}
zip.Save(Response.OutputStream);
}
}
Finally i found the answer!!..It may help someone in future.
Response.ContentType = "application/zip";
Response.AppendHeader("content-disposition", "attachment; filename=Reports.zip");
int PageCount = report.FormatEngine.GetLastPageNumber(new
CrystalDecisions.Shared.ReportPageRequestContext());
if (PageCount >= 1)
{
using (ZipFile zip = new ZipFile())
{
for (int i = 1; i <= PageCount; i++)
{
PdfRtfWordFormatOptions pdfRtfWordOpts = ExportOptions.CreatePdfRtfWordFormatOptions();
DiskFileDestinationOptions destinationOpts = ExportOptions.CreateDiskFileDestinationOptions();
ExportRequestContext req = new ExportRequestContext();
pdfRtfWordOpts.FirstPageNumber = i;
pdfRtfWordOpts.LastPageNumber = i;
pdfRtfWordOpts.UsePageRange = true;
ExportOptions CrExportOptions = report.ExportOptions;
{
CrExportOptions.ExportFormatType = ExportFormatType.PortableDocFormat;
CrExportOptions.FormatOptions = pdfRtfWordOpts;
req.ExportInfo = CrExportOptions;
}
Stream s = report.FormatEngine.ExportToStream(req);
string Name = "Page" + i + ".pdf";
zip.AddEntry(Name, s);
}
zip.Save(Response.OutputStream);
}
}

Memorystream performance issue with multiple users

I have a section in my application that displays a PDF to a user. I'm using memorystream to get this document. Whenever I have more than a handful of users requests a document at the same time the performance of my application slows down. If i have 30+ users it comes to a crawl. Most of my users say it starts to slow as they reach the document. Here is how I call the document
public FileStreamResult GetDocument(bool useDefault)
{
string contentType = string.Empty;
short verificationType = VerificationType();
MemoryStream ms = DocumentToStream(useDefault, out contentType);
if (contentType == string.Empty) contentType = "application/pdf";
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.ContentType = contentType;
HttpContext.Current.Response.AppendHeader("Content-Disposition", "inline;" + FormFileName());
HttpContext.Current.Response.Buffer = true;
HttpContext.Current.Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
HttpContext.Current.Response.OutputStream.Flush();
HttpContext.Current.Response.OutputStream.Close();
HttpContext.Current.Response.End();
ms.Close();
if (verificationType == OBDocVerification.Presentation) SetVerified(verificationType);
return new FileStreamResult(HttpContext.Current.Response.OutputStream, contentType);
}
To get the actual file it does this
private MemoryStream CreatePdfStream(PdfReader pdfDoc, List<MappedField> pdfFields, bool useVerifyButton, bool isLocked, bool isI9, bool isManualUpdate, string state) // 04/26/2018 DS TFS # 3161
{
using (MemoryStream stream = new MemoryStream())
{
PdfStamper stamper = new PdfStamper(pdfDoc, stream);
if (!isLocked)
{
foreach (MappedField mappedFld in pdfFields)
{
if (!string.IsNullOrEmpty(mappedFld.DB_Table))
{
//string v = PDFformFieldValue(mappedFld, this.docLevel);
string v = PDFformFieldValue(mappedFld, this.docLevel, isI9, state); // 10/04/2017 DS TFS # 2768 (added isI9)
if (!string.IsNullOrEmpty(v))
{
stamper.AcroFields.SetField(mappedFld.FormName, v);
}
else
{
stamper.AcroFields.SetField(mappedFld.FormName, string.Empty);
}
if (useVerifyButton)
{
if (!IsPDFformFieldEditable(mappedFld) || !GlobalVariables.IsIE) stamper.AcroFields.SetFieldProperty(mappedFld.FormName, "setfflags", PdfFormField.FF_READ_ONLY, null);
}
}
}
if (isI9) ValidateI9NAFields(ref stamper, pdfFields);
if (!isManualUpdate && GlobalVariables.IsIE) stamper.FormFlattening = true; // 04/26/2018 DS TFS # 3161
}
//else
// stamper.FormFlattening = true;
if (useVerifyButton && GlobalVariables.IsIE)
{
// Add "Verify" button
string alignmentType;
int numberOfPages = pdfDoc.NumberOfPages;
int stampPage = GetVerifyButtonLocation(out alignmentType);
if (stampPage <= 1) stampPage = numberOfPages;
if (stampPage > numberOfPages) stampPage = numberOfPages;
if (alignmentType == string.Empty) alignmentType = "bottom_right";
Rectangle thePage = pdfDoc.GetCropBox(stampPage);
float buttonWidth = 100;
float buttonHeight = 40;
Rectangle ButtonRect = CreateVerifyButtonLocation(thePage, alignmentType, buttonWidth, buttonHeight);
PushbuttonField button = new PushbuttonField(stamper.Writer, ButtonRect, "postSubmit");
button.BackgroundColor = ButtonColor();
button.BorderColor = GrayColor.BLACK;
button.BorderWidth = 1f;
button.BorderStyle = PdfBorderDictionary.STYLE_INSET;
button.TextColor = BaseColor.WHITE;
button.FontSize = 12f;
button.Text = VerifyButtonTitle();
button.Visibility = PushbuttonField.VISIBLE_BUT_DOES_NOT_PRINT;
button.Rotation = pdfDoc.GetPageRotation(stampPage);
PdfFormField field = button.Field;
//field.Put(PdfName.TU, new PdfString("Save changes and return to the folder."));
field.Action = PdfAction.CreateSubmitForm(this.submitUrl, null, PdfAction.SUBMIT_HTML_FORMAT | PdfAction.SUBMIT_INCLUDE_NO_VALUE_FIELDS);
stamper.AddAnnotation(field, stampPage);
}
//else
// stamper.FormFlattening = true;
stamper.Close();
return stream;
}
}
I feel like I may be doing something inefficient here.
This is not a memory stream problem at all. Consider storing a generated stream and then serve it directly. If you have a large pdf file and several users than
your code will be executed several times with same result.

iTextSharp edit PDF's based on SQL Query

I need to edit merging PDF's to have a colored bar on each PDF page based on a value in an SQL database where the PDF filename is also stored. I am not great with C# lists but thought perhaps I could build a supplemental list to the iTextSharp "PDFReader" list then when iterating through the PDFReader list write a conditional statement that says "if list 2 value = "Utilities" then create green square" during the PDF merge process.
protected void Page_Load(object sender, EventArgs e)
{
try
{
if ((Session["AccessLevel"].ToString() == "admin") || (Session["AccessLevel"].ToString() == "worker") || (Session["AccessLevel"].ToString() == "client"))
{
if (Request.QueryString["type"] == "QC")
{
//SqlDataSource2.Update();
}
else
{
}
string checkID = Request.QueryString["id"];
SqlDataReader rdr = null;
SqlConnection con2 = new SqlConnection(sqlConnection);
con2.Open();
//string sqlRowCount = "SELECT COUNT(*) FROM [Attachment] WHERE RequestId = '" + checkID + "' AND AttachType != 'Invoice' AND AttachType != 'Cover Sheet' ORDER BY AttachOrder ASC";
sqlUserName2 = "SELECT AttachmentName,AttachType FROM [Attachment] WHERE RequestId = '" + checkID + "' AND AttachType != 'Invoice' AND AttachType != 'Cover Sheet' ORDER BY AttachOrder ASC";
//SqlCommand cmd = new SqlCommand(sqlRowCount, con2);
//string count = cmd.ExecuteScalar().ToString();
SqlCommand cmd2 = new SqlCommand(sqlUserName2, con2);
rdr = cmd2.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(rdr);
List<PdfReader> readerList = new List<PdfReader>();
List<string> pdfName = new List<string>();
foreach (DataRow row in dt.Rows)
{
PdfReader pdfReader = new PdfReader(Server.MapPath(HttpContext.Current.Request.ApplicationPath + "/uploads/reports/" +
Convert.ToString(row[0])));
readerList.Add(pdfReader);
pdfName.Add(Convert.ToString(row[1]));
//pdfName.Add(rdr["AttachType"].ToString());
}
System.Net.Mime.ContentType contentType = new System.Net.Mime.ContentType();
contentType.MediaType = System.Net.Mime.MediaTypeNames.Application.Pdf;
Document document = new Document(PageSize.A4, 0, 0, 40, 0);
//Get instance response output stream to write output file.
PdfWriter writer = PdfWriter.GetInstance(document, Response.OutputStream);
// document.Header = new HeaderFooter(new Phrase("Header Text"), false);
// Parameters passed on to the function that creates the PDF
String headerText = "";
String footerText = "PAGE";
// Define a font and font-size in points (plus f for float) and pick a color
// This one is for both header and footer but you can also create seperate ones
Font fontHeaderFooter = FontFactory.GetFont("arial", 12f);
fontHeaderFooter.Color = Color.BLACK;
// Apply the font to the headerText and create a Phrase with the result
Chunk chkHeader = new Chunk(headerText, fontHeaderFooter);
Phrase p1 = new Phrase(chkHeader);
// create a HeaderFooter element for the header using the Phrase
// The boolean turns numbering on or off
HeaderFooter header = new HeaderFooter(p1, false);
// Remove the border that is set by default
header.Border = Rectangle.NO_BORDER;
// Align the text: 0 is left, 1 center and 2 right.
header.Alignment = 1;
// add the header to the document
document.Header = header;
// The footer is created in an similar way
// If you want to use numbering like in this example, add a whitespace to the
// text because by default there's no space in between them
if (footerText.Substring(footerText.Length - 1) != " ") footerText += " ";
//string newFooter = footerText + pageCount;
Chunk chkFooter = new Chunk(footerText, fontHeaderFooter);
Phrase p2 = new Phrase(chkFooter);
// Turn on numbering by setting the boolean to true
HeaderFooter footer = new HeaderFooter(p2, true);
footer.Border = Rectangle.NO_BORDER;
footer.Alignment = 1;
document.Footer = footer;
Response.Write(pdfName);
Response.Write("test");
// Open the Document for writing and continue creating its content
document.Open();
foreach (PdfReader reader in readerList)
{
for (int i = 1; i <= reader.NumberOfPages; i++)
{
PdfImportedPage page = writer.GetImportedPage(reader, i);
if ("if list 2 value = "Utilities" then create green square")
{
PdfContentByte cb = writer.DirectContent;
var rect = new iTextSharp.text.Rectangle(200, 200, 100, 100);
rect.Border = iTextSharp.text.Rectangle.LEFT_BORDER | iTextSharp.text.Rectangle.RIGHT_BORDER;
rect.BorderWidth = 5; rect.BorderColor = new BaseColor(2, 3, 0);
cb.Rectangle(rect);
}
document.Add(iTextSharp.text.Image.GetInstance(page));
}
}
document.Close();
Response.AppendHeader("content-disposition", "inline; filename=" + Request.QueryString["id"] + "-Final");
Response.ContentType = "application/pdf";
con2.Close();
Response.Write(pdfName);
}
}
catch
{
// Response.Redirect("~/PDFProblem.aspx", false);
}
}
This is a bit clunky but it works until I refactor it. I simply iterated the second list (pdfName) within the first iTextSharp one (pdfReader) using an incrementing integer to move the second list forward when the first list did:
foreach (PdfReader reader in readerList)
{
for (int i = 1; i <= reader.NumberOfPages; i++)
{
string totalValue = pdfName[nextOne].ToString();
PdfImportedPage page = writer.GetImportedPage(reader, i);
if (totalValue == "Permit")
{
PdfContentByte cb = writer.DirectContent;
var rect = new iTextSharp.text.Rectangle(200, 200, 100, 100);
rect.Border = iTextSharp.text.Rectangle.LEFT_BORDER | iTextSharp.text.Rectangle.RIGHT_BORDER;
rect.BorderWidth = 5; rect.BorderColor = new BaseColor(2, 3, 0);
cb.Rectangle(rect);
}
if (totalValue == "TaxBill")
{
PdfContentByte cb = writer.DirectContent;
var rect = new iTextSharp.text.Rectangle(200, 200, 100, 100);
rect.Border = iTextSharp.text.Rectangle.LEFT_BORDER | iTextSharp.text.Rectangle.RIGHT_BORDER;
rect.BorderWidth = 15; rect.BorderColor = new BaseColor(3, 2, 0);
cb.Rectangle(rect);
}
nextOne = nextOne + 1;
document.Add(iTextSharp.text.Image.GetInstance(page));
}
}

Export to excel in c# showing error and not downloading the excel

My code, where the collection of values retrived from DB and that values stored one by one in datatable.And loading that dataTable to worksheet of Excel
var dataTable = new DataTable();
var sb = new StringBuilder();
var resultvalues=methodtogetvalues() ;
if (resultvalues!= null && resultvalues.Count > 0)
{
var icount = 1;
foreach (var values in resultvalues)
{
if (icount == 1)
{
sb.Append(values.Id);
icount += 1;
}
dataTable.Columns.Add("ID");
dataTable.Rows.Add(values.Id);
}
}
var firstName = context.Request.Params["FirstName"];
var lastName = context.Request.Params["LastName"];
var fileName = firstName+lastName+"_ProgramStatusHistory_"+DateTime.Now;
var tempText = Convert.ToString(sb);
var workBook = new ExpertXls.ExcelLib.ExcelWorkbook(ExpertXls.ExcelLib.ExcelWorkbookFormat.Xlsx_2007);
var accessedRangeStyle = workBook.Styles.AddStyle("ΑccessedRangeStyle");
accessedRangeStyle.Font.Size = 10;
accessedRangeStyle.Font.Bold = true;
accessedRangeStyle.Alignment.VerticalAlignment = ExpertXls.ExcelLib.ExcelCellVerticalAlignmentType.Center;
accessedRangeStyle.Alignment.HorizontalAlignment = ExpertXls.ExcelLib.ExcelCellHorizontalAlignmentType.Left;
workBook.Worksheets.AddWorksheet();
var workSheet = workBook.Worksheets[0];
workSheet.LoadDataTable(dataTable, 1, 1, true);
workSheet.AutofitColumns();
workBook.Worksheets.RemoveWorksheet("Sheet2");
workBook.Worksheets.RemoveWorksheet("Sheet3");
workBook.Worksheets.RemoveWorksheet("Sheet4");
workBook.LicenseKey = "gqmworCworOysrWitKyyorGzrLOwrLu7u7s=";
context.Response.Clear();
context.Response.Buffer = true;
context.Response.Charset = "";
context.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
context.Response.AddHeader("content-disposition", "attachment;filename=" + fileName);
using (var MyMemoryStream = new System.IO.MemoryStream())
{
workBook.Save(MyMemoryStream);
MyMemoryStream.WriteTo(context.Response.OutputStream);
context.Response.Flush();
context.Response.End();
}
This code simply shows an alert box with the error message "Error".
I don't understand whats wrong. Can anyone redirect me with correct way.
I would move this line of code outside the using statement:
context.Response.End();
also show your catch block. It's unlikely to be giving just a message of 'Error' I would suggest placing a breakpoint in the catch block and looking inside the error object.

ITextSharp Adding Multiple PDFStampers to memoryStream

I have a asp.net application that uses ITextSharp 5.4.5.0 to generate certificates. I have the code that generates one certificate working fine, but when I try to bundle these one page certificates into a single multi-page PDF and output the memorystream to the browser I get an error from Adobe Acrobat.
I have a feeling that I'm not adding eachof my byte arroys correctly, but I'm at a loss.
Here is the calling code:
protected void btnMakeCerts_Click(object sender, EventArgs e)
{
ICAgileEntities icae = new ICAgileEntities();
int classid =int.Parse(Request.QueryString["id"]);
var currentClass = (from c in icae.Classes
where c.id == classid
select c).FirstOrDefault();
Response.Clear();
Response.BufferOutput = true;
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment; filename=AllCertificates-" + currentClass.Title + ".pdf");
var pagesAll = new List<byte[]>();
pagesAll = Helper.Certificate.ProcessClassCerts(classid);
MemoryStream ms = new MemoryStream();
PdfConcatenate whole = new PdfConcatenate(ms);
foreach (byte[] pageAll in pagesAll)
{
PdfReader partReader = new PdfReader(pageAll);
whole.AddPages(partReader);
partReader.Close();
}
Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
Response.Flush();
Response.End();
}
And this creates the individual pages and returns a byte array:
public static List<byte[]> ProcessClassCerts(int classId)
{
var icae = new ICAgileEntities();
string filename = DateTime.Now.ToString().Replace(#"/", "").Replace(":", "").Replace(" ", "") + ".pdf";
string sFileDir = ConfigurationManager.AppSettings["ServerPath"] + (#"\images\sigs\");
var currentClass = (from c in icae.Classes
where c.id == classId
select c).FirstOrDefault();
//make the Instructor Names
String instName = "test";
var students = (from up in icae.UserProfiles
from cl in up.UserProfile_Class_Details
where cl.ClassId == classId && cl.IsCertPaid == true && cl.IsClassPaid == true
select up);
var currentCourse = (from s in icae.Courses
where s.id == currentClass.CourseID
select s).FirstOrDefault();
var pageBytes = (byte[])null;
var pagesAll = new List<byte[]>();
try
{
string path = ConfigurationManager.AppSettings["ServerPath"] + #"\PDFs\";
int i = 1;
foreach (var s in students)
{
PdfStamper pst = null;
MemoryStream mstr = null;
using (mstr = new MemoryStream())
{
try
{
PdfReader reader = new PdfReader(path + #"\certFormPDF.pdf"); //new PdfReader(GetTemplateBytes());
pst = new PdfStamper(reader, mstr);
var acroFields = pst.AcroFields;
acroFields.SetField("Awardee Name", s.DisplayName);
pst.FormFlattening = true;
pst.SetFullCompression();
}
finally
{
if (pst != null)
pst.Close();
}
}
pageBytes = mstr.ToArray();
pagesAll.Add(pageBytes);
i++;
}
}
finally
{
}
return pagesAll;
}
Thanks for any help you can provide

Categories