How to export GridView to excel using OpenXML in c#? [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I know people asked similar questions already. But the solutions are not what I am looking for. For my case, our GridView holds at least a million of records. In addition, our customer doesn't like the warning message from excel 2007. Because of the warning message, we cannot use the most common way that uses GridView.RenderControl(). So we decided to try OpenXML. But from all the sample codes I have found, to create an excel file using OpenXML, it seems that you have to loop each row&column of the GridView and write to each cell of an excel file. It will take a good amount of time. Does any one know if there is better/faster solution? Also, we cannot use third party DLLs because of security reason. Thanks.

here is a method that I use to Export DataTable to Excel I created a class public static class Extensions to house these methods
internal static void ExportToXcel_MyDataTable(DataTable dt, string fileName, Page page)
{
var recCount = dt.Rows.Count;
RemoveHtmlSpecialChars(dt);
fileName = string.Format(fileName, DateTime.Now.ToString("MMddyyyy_hhmmss"));
var xlsx = new XLWorkbook();
var ws = xlsx.Worksheets.Add("Some Report Name");
ws.Style.Font.Bold = true;
ws.Cell("C5").Value = "MY TEST EXCEL REPORT";
ws.Cell("C5").Style.Font.FontColor = XLColor.Black;
ws.Cell("C5").Style.Font.SetFontSize(16.0);
ws.Cell("E5").Value = DateTime.Now.ToString("MM/dd/yyyy HH:mm");
ws.Range("C5:E5").Style.Font.SetFontSize(16.0);
ws.Cell("A7").Value = string.Format("{0} Records", recCount);
ws.Style.Font.Bold = false;
ws.Cell(9, 1).InsertTable(dt.AsEnumerable());
ws.Row(9).InsertRowsBelow(1);
// ws.Style.Font.FontColor = XLColor.Gray;
ws.Columns("1-8").AdjustToContents();
ws.Tables.Table(0).ShowAutoFilter = true;
ws.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
DynaGenExcelFile(fileName, page, xlsx);
}
private static void DynaGenExcelFile(string fileName, Page page, XLWorkbook xlsx)
{
page.Response.ClearContent();
page.Response.ClearHeaders();
page.Response.ContentType = "application/vnd.ms-excel";
page.Response.AppendHeader("Content-Disposition", string.Format("attachment;filename={0}.xlsx", fileName));
using (MemoryStream memoryStream = new MemoryStream())
{
xlsx.SaveAs(memoryStream);
memoryStream.WriteTo(page.Response.OutputStream);
}
page.Response.Flush();
page.Response.End();
}
If you have Html / special characters in the DataTable this method will remove them replacing the row data with string.Empty
/// <summary>
/// Remove all HTML special characters from datatable field if they are present
/// </summary>
/// <param name="dt"></param>
private static void RemoveHtmlSpecialChars(DataTable dt)
{
for (int rows = 0; rows < dt.Rows.Count; rows++)
{
for (int column = 0; column < dt.Columns.Count; column++)
{
dt.Rows[rows][column] = dt.Rows[rows][column].ToString().Replace(" ", string.Empty);
}
}
}

Related

Which C# project should I use for a certain requirement? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 months ago.
Improve this question
I've got a request from a stakeholder who wants us to automate the following procedure.
Go to the CMS website (In-house application)
Take a picture of the report.
Send an email to stakeholders with the reports attached.
Note: This procedure must be repeated on a daily basis.
And I'm not sure which project to choose for the above need; at the moment, all I can think of is a Console Application, but I'm not sure much about it.
Any assistance would be much appreciated.
Code For Screenshot - Selenium C#
public class ScreenShotRepository
{
public static void TakeScreenShot(IWebDriver Driver, string filename, List<string> text = null)
{
var bytesArr = Driver.TakeScreenshot(new VerticalCombineDecorator(new ScreenshotMaker()));
var screenshotImage = (System.Drawing.Image)((new ImageConverter()).ConvertFrom(bytesArr));
WriteToPDF(new List<System.Drawing.Image>() { screenshotImage }, filename, text);
}
public static void WriteToPDF(List<System.Drawing.Image> screenshots, string filename, List<string> text)
{
var fileStream = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);
var document = new Document(new iTextSharp.text.Rectangle(0, 0, screenshots[0].Width, screenshots[0].Height), 0, 0, 0, 0);
var writer = PdfWriter.GetInstance(document, fileStream);
document.Open();
var content = writer.DirectContent;
var font = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
for (int i = 0; i < screenshots.Count; i++)
{
var image = iTextSharp.text.Image.GetInstance(screenshots[i], screenshots[i].RawFormat);
document.Add(image);
WriteText(content, font, text);
if (i + 1 != screenshots.Count)
document.NewPage();
}
document.Close();
writer.Close();
}
public static void WriteText(PdfContentByte content, BaseFont font, List<string> text)
{
content.BeginText();
content.SetColorFill(BaseColor.GREEN);
content.SetFontAndSize(font, 40);
for (int j = 0; j < text.Count; j++)
content.ShowTextAligned(Element.ALIGN_LEFT, text[j].ToString(), 50, 50 + 50 * j, 0);
content.EndText();
}
}
You could make this a Windows Service, because of the daily call requirement.
However, the simplest way is indeed a console application that you schedule to run using your operating systems task scheduler.
And as far as the requirements go, why can't the reporting system output a PDF? Taking a screenshot of another software is already a really makeshift solution if it were third-party, taking screenshots of your own reporting software just says whoever programs the inhouse CMS system is... not up to the task if there is a requirement to automate it outside of their domain.

How to remove export to excel warning when exporting datatable

I have the following code, the datatable already has the data and I want to export it to excel.
However I get the following warning, I tried xlsx and it doesnt work.
I also tried csv, and the data does not open into columns as I need.
public static void ExportDatatabletoExcel(DataTable dt, List<string> columnNames)
{
try
{
const string attachment = "attachment; filename=elreport.xls";
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.AddHeader("content-disposition", attachment);
HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
string tab = "";
foreach (DataColumn dc in dt.Columns)
{
if (!columnNames.Contains(dc.ColumnName)) continue;
HttpContext.Current.Response.Write(tab + dc.ColumnName);
tab = "\t";
}
HttpContext.Current.Response.Write("\n");
int i;
foreach (DataRow dr in dt.Rows)
{
tab = "";
for (i = 0; i < dt.Columns.Count; i++)
{
if(!columnNames.Contains(dt.Columns[i].ColumnName)) continue;
HttpContext.Current.Response.Write(tab + dr[i].ToString());
tab = "\t";
}
HttpContext.Current.Response.Write("\n");
}
HttpContext.Current.Response.End();
}
catch (Exception ex)
{
string errorMessage = String.Format("ExportToExcelError: {0}", ex.Message);
LoggingService.LogError(LoggingCategory.General, ex, errorMessage);
throw;
}
}
Error is:
There are two sure ways to remove the warning.
Build a valid .xlsx file using the OpenXML API or EPPlus API (EPPlus is easier and actually supports OleDB imports)
Build the file as .csv with .csv extension, but leave the content-type as Excel so that it opens with Excel. However, the way you are building the file you may have issues with Excel reading the content correctly, which needs to be addressed:
Excel can only read CSV if it is formatted in certain ways. Also the encoding has to be windows 1252 assuming you are using Excel for windows, or it won't handle foreign chars. Also leading zeros from zip codes etc. need to be dealt with specially for Excel.
public static class CSVExportUtility
{
/// <summary>
/// Open a datatable in Excel
/// </summary>
/// <param name="dt"></param>
/// <param name="fileName"></param>
public static void OpenAsCSV(DataTable dt, string fileName)
{
CSVExportUtility.OpenAsCSV(DataTableToCSV(dt), fileName); // now open the file
} // OpenAsCSV
/// <summary>
/// open the content in the browser as a CSV
/// </summary>
/// <param name="sbCSVFileData"></param>
/// <param name="filename"></param>
public static void OpenAsCSV(StringBuilder sbCSVFileData, string fileName)
{
if (HttpContext.Current == null || HttpContext.Current.Response == null)
return;
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader(
"content-disposition", string.Format("attachment; filename={0}", fileName));
HttpContext.Current.Response.ContentType = "application/ms-excel";
// This is a little tricky. Would like to use utf-8 or unicode... but Excel on Windows uses 1252 by default so we need to keep the same so most users can read the file.
// At some point, we may need to actually convert our text from whatever .NET uses to 1252, but at the moment they seem similar enough that it is okay
HttpContext.Current.Response.ContentEncoding = Encoding.GetEncoding(1252);
// render the htmlwriter into the response
HttpContext.Current.Response.Write(sbCSVFileData.ToString());
HttpContext.Current.Response.End();
}
static StringBuilder DataTableToCSV(DataTable dt)
{
StringBuilder sb = new StringBuilder();
foreach (DataColumn dc in dt.Columns)
{
if (dc == dt.Columns[dt.Columns.Count - 1])
CSVExportUtility.AddFieldForCSV(dc.ColumnName, sb, false, true);
else
CSVExportUtility.AddFieldForCSV(dc.ColumnName, sb, true, false);
}
foreach (DataRow dr in dt.Rows)
{
foreach (DataColumn dc in dt.Columns)
{
if (dc == dt.Columns[dt.Columns.Count - 1])
CSVExportUtility.AddFieldForCSV(FormatDataValue(dr[dc.ColumnName]), sb, false, true);
else
CSVExportUtility.AddFieldForCSV(FormatDataValue(dr[dc.ColumnName]), sb, true, false);
}
}
return sb;
}
static string FormatDataValue(object dv)
{
if (dv == null)
return null;
if (dv is DateTime)
return ((DateTime)dv).ToShortDateString();
else
return dv.ToString();
}
/// <summary>
/// export text to a csv
/// </summary>
/// <param name="text"></param>
/// <param name="sbCSV"></param>
/// <param name="appendTrailingComma"></param>
/// <param name="endOfRow"></param>
public static void AddFieldForCSV(string text, StringBuilder sbCSV, bool appendTrailingComma, bool endOfRow)
{
// shouldn't start or end with whitespace, escape quotes
if (text != null)
text = text.Trim().Replace("\"", "\"\"");
// quote field
int testInt;
if (text != null && text.Trim().Length > 1 && text.Trim()[0] == '0' && int.TryParse(text.Trim(), out testInt))
{ // if text is numeric and starts with '0' tell excel to treat as string and not strip the zero. This ONLY works if it's numeric! Otherwise it fails, example ="a,b" will use 2 cells
text = "=\"" + text.Trim() + "\"";
}
else
{
text = "\"" + text + "\"";
}
sbCSV.Append(text);
if (appendTrailingComma)
sbCSV.Append(",");
if (endOfRow)
sbCSV.AppendLine();
}
}
If you are looking to export a GridView instead of a DataTable, that explanation is at:
http://atakala.com/Browser/Item.aspx?user_id=amos&dict_id=2325
; much of the code is similar (CSVExportUtility methods)
This answer from How to suppress the file corrupt warning at Excel download? addresses some of the problem. I recommend checking out some of the other answers as well.
The alert is a new security feature in Excel 2007 called Extension
Hardening, which ensures that the file content being opened matches
the extension type specified in the shell command that is attempting
to open the file.
...
This issue is still being investigated, but a fix is not likely until
Office 14 given the nature of the complexity of the code, and the fact
that Excel does not want to lower the security measure to workaround
IE open behaviors without a full understanding of the consequences for
other browser users.
Also, this comment might help.
I think that only applies if you're using CSV and save as XLS.
However, if you construct a real excel file, then it should be fine.
CF9 cfspreadsheet will be your friend. :) – Henry Jun 25 '09 at 23:53
Other sources to check:
How to Suppress Extension Warning in Excel
How do you generate an Excel 2007 file in ASP.NET without getting a warning message?
How to avoid warning on opening a programmatically generated Excel file

How to create CSV and PDF using array as a data source in c# [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a class
public class Data
{
public string name{ get; set; }
public int age { get; set; }
}
And I have a method which accept array of data, I need to generate csv and pdf from the upcoming data.
public void ExportToCSV(Data[] data)
{
// write code to generate csv
}
public void ExportToPdf(Data[] data)
{
// write code to generate pdf
}
Please suggest.
I generated Excel like this, and wondering to have similar code which generate csv and pdf. What change will be needed?
public void ExportToExcel(Data[] data)
{
var grid = new GridView();
grid.DataSource = data;
grid.DataBind();
Response.ClearContent();
Response.AddHeader("Content-type", "application/vnd.ms-excel");
Response.AddHeader("content-disposition", "attachment;filename=export.xls");
Response.ContentType = "application/excel";
var swr = new StringWriter();
var tw = new HtmlTextWriter(swr);
grid.RenderControl(tw);
Response.Write(swr.ToString());
Response.Flush();
Response.End();
tw.Close();
swr.Close();
}
try
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\Test\yourFile.csv"))
{
file.WriteLine("name,age");
foreach(var item in data)
{
file.WriteLine(String.Format("{0},{1}", item.name, item.age));
}
}
Use LINQ:
string csv = data.ToLidt()
.Select(i => string.Format("{0}, {1}", i.name, i.age.ToString())
.Aggregate((a, b) => string.Format("{0}\r\n{1}"));
Update:
Well, technically, your Excel generation code is not creating Excel. You're just using GridView render control class, which I doubt to create Excel at all.
But to create PDF and any other document, your path is just the same:
Creating the file on the server using some third-party libraries
Sometimes that file needs to be saved temporarily, which in that case you can look here.
You should set the correct MIME Type on the response, so that browser knows what it has to do with the content.
You should set Content-Disposition header, so that browser downloads the file, instead of opening it.
And you at last write the file to the response stream as a binary array.

Merging two PDF documents into one [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Can I merge two or more PDFs in asp.net? I know I can do Word and Excel files using interop. But can I merge PDFs?
Please suggest any suggestions or any links.
Try iTextSharp:
iTextSharp is a C# port of iText, and open source Java library for
PDF generation and manipulation. It can be used to create PDF
documents from scratch, to convert XML to PDF (using the extra XFA
Worker DLL), to fill out interactive PDF forms, to stamp new content
on existing PDF documents, to split and merge existing PDF documents,
and much more.
Here's an article on how to do it.
using System.Text.RegularExpressions;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
using iTextSharp.text;
//Call this method in main with parameter
public static void MergePages(string outputPdfPath, string[] lstFiles)
{
PdfReader reader = null;
Document sourceDocument = null;
PdfCopy pdfCopyProvider = null;
PdfImportedPage importedPage;
sourceDocument = new Document();
pdfCopyProvider = new PdfCopy(sourceDocument,
new System.IO.FileStream(outputPdfPath, System.IO.FileMode.Create));
sourceDocument.Open();
try
{
for (int f = 0; f < lstFiles.Length - 1; f++)
{
int pages = 1;
reader = new PdfReader(lstFiles[f]);
//Add pages of current file
for (int i = 1; i <= pages; i++)
{
importedPage = pdfCopyProvider.GetImportedPage(reader, i);
pdfCopyProvider.AddPage(importedPage);
}
reader.Close();
}
sourceDocument.Close();
}
catch (Exception ex)
{
throw ex;
}
}

How do I extract images from a pdf in c#? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
How do I extract an image from a pdf file, using c#? Thanks!
You could use iTextSharp. Here's an example.
Docotic.Pdf library can be used to extract images from PDFs.
Here is a sample that shows how to iterate trough pages and extract all images from each PDF page:
static void ExtractImagesFromPdfPages()
{
string path = "";
using (PdfDocument pdf = new PdfDocument(path))
{
for (int i = 0; i < pdf.Pages.Count; i++)
{
for (int j = 0; j < pdf.Pages[i].Images.Count; j++)
{
string imageName = string.Format("page{0}-image{1}", i, j);
string imagePath = pdf.Pages[i].Images[j].Save(imageName);
}
}
}
}
The library won't resample images. It will save them exactly the same as in PDF.
Disclaimer: I work for Bit Miracle, vendor of the library.

Categories

Resources