I am using a method that accepts datatable and transform it into CSV. The problem is, (1) when I try to call this method, succeeding process/commands will never be executed. Also (2) list box contents from the calling form were cleared out after calling this method. Can anyone help me out on this? I have included the method below for reference.
public void DataTableToCSV(string fileName, DataTable dt)
{
Response.Clear();
Response.AddHeader("content-disposition", string.Format("attachment;filename={0}.csv", fileName + DateTime.Now.ToString().Replace(" ", "").Replace(":", "").Replace(" ", "").Replace("/", "")));
Response.Charset = "";
Response.ContentType = "application/vnd.csv";
System.IO.StringWriter sWriter;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sWriter = new System.IO.StringWriter(sb);
string Str;
for (int k = 0; k <= (dt.Columns.Count - 1); k++)
{
sWriter.Write(dt.Columns[k].ColumnName + ",");
}
sWriter.WriteLine(",");
for (int i = 0; i <= (dt.Rows.Count - 1); i++)
{
for (int j = 0; j <= (dt.Columns.Count - 1); j++)
{
Str = (dt.Rows[i][j].ToString().Replace(",", ""));
if (Str == " ")
Str = "";
Str = (Str + ",");
sWriter.Write(Str);
}
sWriter.WriteLine();
}
sWriter.Close();
Response.Write(sb.ToString());
Response.End();
}
Regarding (1) - Response.End() throws ThreadAbortException internally, which basically terminates the normal page life-cycle and 'jumps ahead' to the EndRequest event. So anything immediately following a call to DataTableToCSV() will not be called.
Hope this helps..
Create a second page that returns the CSV. Put a Meta refresh tag in the head of your page which redirects to this page. Because the reponse is a file, you'll never actually be redirected, but the file save dialogue will appear.
Related
I'm exporting some data from a GridView to a .txt file.
This is the code:
private void ExportGridToExcel()
{
Response.Clear();
Response.Buffer = true;
Response.Charset = "";
string FileName = "Export" + DateTime.Now + ".txt";
StringBuilder strbldr = new StringBuilder();
Response.ContentType = "application/text";
Response.AddHeader("Content-Disposition", "attachment;filename=" + FileName);
Response.ContentEncoding = System.Text.Encoding.Unicode;
Response.BinaryWrite(System.Text.Encoding.Unicode.GetPreamble());
Response.Cache.SetCacheability(HttpCacheability.NoCache);
for (int i = 0; i < GridView1.Columns.Count; i++)
{
//separting header columns text with comma operator
strbldr.Append(GridView1.Columns[i].HeaderText + ',');
}
//appending new line for gridview header row
strbldr.Append("\n");
for (int j = 0; j < GridView1.Rows.Count; j++)
{
for (int k = 0; k < GridView1.Columns.Count; k++)
{
//separating gridview columns with comma
strbldr.Append(GridView1.Rows[j].Cells[k].Text + ',');
strbldr.Replace("<", "<");
strbldr.Replace(">", ">");
}
//appending new line for gridview rows
strbldr.Append("\n");
}
GridView1.AllowPaging = false;
Response.Output.Write(strbldr.ToString());
Response.End();
}
protected void Button3_Click(object sender, EventArgs e)
{
ExportGridToExcel();
}
This works, however I need to remove all html tags in the export as the above code seems to add <p> tags to the different columns? Anybody know how I can do this?
You could use utility function based on regex to remove html tags:
public string RemoveHtmlTags(string source)
{
return Regex.Replace(source, "<.*?>", "");
}
This will replace all tags like "<b>" or "<span/>" with empty string.
I am using the following code to write a file to the Desktop.
string submittedFilePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
int i = 0;
StreamWriter sw = null;
sw = new StreamWriter(submittedFilePath, false);
for (i = 0; i < PSOLib.table.Columns.Count - 1; i++)
{
sw.Write(PSOLib.table.Columns[i].ColumnName + ";");
}
sw.Write(PSOLib.table.Columns[i].ColumnName);
sw.WriteLine();
foreach (DataRow row in PSOLib.table.Rows)
{
object[] array = row.ItemArray;
for (i = 0; i < array.Length - 1; i++)
{
sw.Write(array[i].ToString() + ";");
}
sw.Write(array[i].ToString());
sw.WriteLine();
}
sw.Close();
However whenever I try to invoke the method I get:
Access to the path 'C:\\Users\\User\\Desktop' is denied.
System.UnauthorizedAccessException.
You didn't specify a file for your StreamWriter, but a folder.
This should do it:
string submittedFilePath =
Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\myFile.txt.";
I'm working on a application which will export my DataGridView called scannerDataGridView to a csv file.
Found some example code to do this, but can't get it working. Btw my datagrid isn't databound to a source.
When i try to use the Streamwriter to only write the column headers everything goes well, but when i try to export the whole datagrid including data i get an exeption trhown.
System.NullReferenceException: Object reference not set to an instance
of an object. at Scanmonitor.Form1.button1_Click(Object sender,
EventArgs e)
Here is my Code, error is given on the following line:
dataFromGrid = dataFromGrid + ',' + dataRowObject.Cells[i].Value.ToString();
//csvFileWriter = StreamWriter
//scannerDataGridView = DataGridView
private void button1_Click(object sender, EventArgs e)
{
string CsvFpath = #"C:\scanner\CSV-EXPORT.csv";
try
{
System.IO.StreamWriter csvFileWriter = new StreamWriter(CsvFpath, false);
string columnHeaderText = "";
int countColumn = scannerDataGridView.ColumnCount - 1;
if (countColumn >= 0)
{
columnHeaderText = scannerDataGridView.Columns[0].HeaderText;
}
for (int i = 1; i <= countColumn; i++)
{
columnHeaderText = columnHeaderText + ',' + scannerDataGridView.Columns[i].HeaderText;
}
csvFileWriter.WriteLine(columnHeaderText);
foreach (DataGridViewRow dataRowObject in scannerDataGridView.Rows)
{
if (!dataRowObject.IsNewRow)
{
string dataFromGrid = "";
dataFromGrid = dataRowObject.Cells[0].Value.ToString();
for (int i = 1; i <= countColumn; i++)
{
dataFromGrid = dataFromGrid + ',' + dataRowObject.Cells[i].Value.ToString();
csvFileWriter.WriteLine(dataFromGrid);
}
}
}
csvFileWriter.Flush();
csvFileWriter.Close();
}
catch (Exception exceptionObject)
{
MessageBox.Show(exceptionObject.ToString());
}
LINQ FTW!
var sb = new StringBuilder();
var headers = dataGridView1.Columns.Cast<DataGridViewColumn>();
sb.AppendLine(string.Join(",", headers.Select(column => "\"" + column.HeaderText + "\"").ToArray()));
foreach (DataGridViewRow row in dataGridView1.Rows)
{
var cells = row.Cells.Cast<DataGridViewCell>();
sb.AppendLine(string.Join(",", cells.Select(cell => "\"" + cell.Value + "\"").ToArray()));
}
And indeed, c.Value.ToString() will throw on null value, while c.Value will correctly convert to an empty string.
A little known feature of the DataGridView is the ability to programmatically select some or all of the DataGridCells, and send them to a DataObject using the method DataGridView.GetClipboardContent(). Whats the advantage of this then?
A DataObject doesn't just store an object, but rather the representation of that object in various different formats. This is how the Clipboard is able to work its magic; it has various formats stored and different controls/classes can specify which format they wish to accept. In this case, the DataGridView will store the selected cells in the DataObject as a tab-delimited text format, a CSV format, or as HTML (*).
The contents of the DataObject can be retrieved by calling the DataObject.GetData() or DataObject.GetText() methods and specifying a predefined data format enum. In this case, we want the format to be TextDataFormat.CommaSeparatedValue for CSV, then we can just write that result to a file using System.IO.File class.
(*) Actually, what it returns is not, strictly speaking, HTML. This format will also contain a data header that you were not expecting. While the header does contain the starting position of the HTML, I just discard anything above the HTML tag like myString.Substring(IndexOf("<HTML>"));.
Observe the following code:
void SaveDataGridViewToCSV(string filename)
{
// Choose whether to write header. Use EnableWithoutHeaderText instead to omit header.
dataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText;
// Select all the cells
dataGridView1.SelectAll();
// Copy selected cells to DataObject
DataObject dataObject = dataGridView1.GetClipboardContent();
// Get the text of the DataObject, and serialize it to a file
File.WriteAllText(filename, dataObject.GetText(TextDataFormat.CommaSeparatedValue));
}
Now, isn't that better? Why re-invent the wheel?
Hope this helps...
Please check this code.its working fine
try
{
//Build the CSV file data as a Comma separated string.
string csv = string.Empty;
//Add the Header row for CSV file.
foreach (DataGridViewColumn column in dataGridView1.Columns)
{
csv += column.HeaderText + ',';
}
//Add new line.
csv += "\r\n";
//Adding the Rows
foreach (DataGridViewRow row in dataGridView1.Rows)
{
foreach (DataGridViewCell cell in row.Cells)
{
if (cell.Value != null)
{
//Add the Data rows.
csv += cell.Value.ToString().TrimEnd(',').Replace(",", ";") + ',';
}
// break;
}
//Add new line.
csv += "\r\n";
}
//Exporting to CSV.
string folderPath = "C:\\CSV\\";
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
File.WriteAllText(folderPath + "Invoice.csv", csv);
MessageBox.Show("");
}
catch
{
MessageBox.Show("");
}
Found the problem, the coding was fine but i had an empty cell that gave the problem.
Your code was almost there... But I made the following corrections and it works great. Thanks for the post.
Error:
string[] output = new string[dgvLista_Apl_Geral.RowCount + 1];
Correction:
string[] output = new string[DGV.RowCount + 1];
Error:
System.IO.File.WriteAllLines(filename, output, System.Text.Encoding.UTF8);
Correction:
System.IO.File.WriteAllLines(sfd.FileName, output, System.Text.Encoding.UTF8);
The line "csvFileWriter.WriteLine(dataFromGrid);" should be moved down one line below the closing bracket, else you'll get a lot of repeating results:
for (int i = 1; i <= countColumn; i++)
{
dataFromGrid = dataFromGrid + ',' + dataRowObject.Cells[i].Value.ToString();
}
csvFileWriter.WriteLine(dataFromGrid);
I think this is the correct for your SaveToCSV function : ( otherwise Null ...)
for (int i = 0; i < columnCount; i++)
Not :
for (int i = 1; (i - 1) < DGV.RowCount; i++)
This is what I been using in my projects:
void export_csv(string file, DataGridView grid)
{
using (StreamWriter csv = new StreamWriter(file, false))
{
int totalcolms = grid.ColumnCount;
foreach (DataGridViewColumn colm in grid.Columns) csv.Write(colm.HeaderText + ',');
csv.Write('\n');
string data = "";
foreach (DataGridViewRow row in grid.Rows)
{
if (row.IsNewRow) continue;
data = "";
for (int i = 0; i < totalcolms; i++)
{
data += (row.Cells[i].Value ?? "").ToString() + ',';
}
if (data != string.Empty) csv.WriteLine(data);
}
}
}
I can export my radgrid to an excel file but I want to add some more info into the sheet.
If it is possible, I would appreciate for a tutorial/sample code for doing a custom excel file generation.
<tel:radgrid runat="server" id="mygrid" skinid="RadGrid_Search_Standard">
<ExportSettings HideStructureColumns="true" />
</tel:radgrid>
Grid is databound with some datatable and I need to add some data
to add some strings above
mygrid.MasterTableView.ExportToWord()
Here's some code that I use with a Telerik Grid, rather than using the ExportToExcel function they've provided I created my own button that fires it's own export event.
I have a function (not included) called getDataSource that I use to populate the grid, you could override this or create your own to fetch the data into a DataTable and add any rows/columns/data as you see fit.
//export button calls this
private void ExportReport()
{
SetPublicVariables();
System.Data.DataTable dt = GetDataSource(false);
string exportData = buildCSVExportString(dt);
string filename = string.Format("{0} - {1}.csv",
(Master as MasterPages.Drilldown).Titlelbl.Text, CampaignTitle);
if (filename.Length > 255) filename = filename.Substring(0, 255);
ExportCSV(exportData, filename);
}
//build a string CSV
public static string buildCSVExportString(DataTable exportDT)
{
StringBuilder exportData = new StringBuilder();
// get headers.
int iColCount = exportDT.Columns.Count;
for (int i = 0; i < iColCount; i++)
{
exportData.Append(exportDT.Columns[i].ToString());
if (i < iColCount - 1)
{
exportData.Append(",");
}
}
exportData.Append(System.Environment.NewLine);
// get rows.
foreach (DataRow dr in exportDT.Rows)
{
for (int i = 0; i < iColCount; i++)
{
if (!Convert.IsDBNull(dr[i]))
{
//If the variable is a string it potentially has charaters that can't be parsed properly.
//this fixes the comma issue(which adds aditional columns). Replace and escape " with "".
if (dr[i] is string)
exportData.Append(String.Format(#"""{0}""", ((string)dr[i]).Replace("\"", #"""""")));
else
exportData.Append(dr[i].ToString());
}
if (i < iColCount - 1)
{
exportData.Append(",");
}
}
exportData.Append(System.Environment.NewLine);
}
return exportData.ToString();
}
public void ExportCSV(string content, string filename)
{
filename = RemoveIllegalPathChars(filename);
HttpResponse Response = HttpContext.Current.Response;
string ext = System.IO.Path.GetExtension(filename);
Response.ClearHeaders();
Response.AddHeader("Content-Disposition", string.Format("attachment;filename=\"{0}\"", filename));
Response.ContentType = "text/csv; charset-UTF-8;";
Response.Clear();
Response.Write(content);
Response.End();
}
A possible way would be to modify the HTML code just before exporting. Here is how.
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
RadGridName.GridExporting += (s, a) =>
{
string myHtmlCode = "<span>My HTML code goes here</span>";
a.ExportOutput = a.ExportOutput.Replace("<body>", "<body>" + myHtmlCode);
};
}
This should work for both Excel (not ExcelML) and Word.
Good luck
The only thing you need to do is add your additional page info to the ExportOutput of your arg
void yourRadGridID_GridExporting(object sender, GridExportingArgs e)
{
string additionalPageInfo= "your html code for the additional page info goes here";
e.ExportOutput = e.ExportOutput.Replace("`<body>`", "`<body>`" + additionalPageInfo);
}
Currently have a DataTable, but wish to stream it to the user via a WebHandler. FileHelpers has CommonEngine.DataTableToCsv(dt, "file.csv"). However it saves it to a file. How can I save it to a stream instead? I know how to do it when I know the columns in advanced or they don't change, but I want to generate the column headings straight from the data table.
If I know the columns I just create the class:
[DelimitedRecord(",")]
public class MailMergeFields
{
[FieldQuoted()]
public string FirstName;
[FieldQuoted()]
public string LastName;
}
Then use FileHelperEngine and add the records:
FileHelperEngine engine = new FileHelperEngine(typeof(MailMergeFields));
MailMergeFields[] merge = new MailMergeFields[dt.Rows.Count + 1];
// add headers
merge[0] = new MailMergeFields();
merge[0].FirstName = "FirstName";
merge[0].LastName = "LastName";
int i = 1;
// add records
foreach (DataRow dr in dt.Rows)
{
merge[i] = new MailMergeFields();
merge[i].FirstName = dr["Forename"];
merge[i].LastName = dr["Surname"];
i++;
}
Finally write to a stream:
TextWriter writer = new StringWriter();
engine.WriteStream(writer, merge);
context.Response.Write(writer.ToString());
Unfortunately as I don't know the columns before hand, I can't create the class before hand.
You can just write something quickly yourself:
public static class Extensions
{
public static string ToCSV(this DataTable table)
{
var result = new StringBuilder();
for (int i = 0; i < table.Columns.Count; i++)
{
result.Append(table.Columns[i].ColumnName);
result.Append(i == table.Columns.Count - 1 ? "\n" : ",");
}
foreach (DataRow row in table.Rows)
{
for (int i = 0; i < table.Columns.Count; i++)
{
result.Append(row[i].ToString());
result.Append(i == table.Columns.Count - 1 ? "\n" : ",");
}
}
return result.ToString();
}
}
And to test:
public static void Main()
{
DataTable table = new DataTable();
table.Columns.Add("Name");
table.Columns.Add("Age");
table.Rows.Add("John Doe", "45");
table.Rows.Add("Jane Doe", "35");
table.Rows.Add("Jack Doe", "27");
var bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(table.ToCSV());
MemoryStream stream = new MemoryStream(bytes);
StreamReader reader = new StreamReader(stream);
Console.WriteLine(reader.ReadToEnd());
}
EDIT: Re your comments:
It depends on how you want your csv formatted but generally if the text contains special characters, you want to enclose it in double quotes ie: "my,text". You can add checking in the code that creates the csv to check for special characters and encloses the text in double quotes if it is. As for the .NET 2.0 thing, just create it as a helper method in your class or remove the word this in the method declaration and call it like so : Extensions.ToCsv(table);
Update 1
I have modified it to use StreamWriter instead, add an option to check if you need column headers in your output.
public static bool DataTableToCSV(DataTable dtSource, StreamWriter writer, bool includeHeader)
{
if (dtSource == null || writer == null) return false;
if (includeHeader)
{
string[] columnNames = dtSource.Columns.Cast<DataColumn>().Select(column => "\"" + column.ColumnName.Replace("\"", "\"\"") + "\"").ToArray<string>();
writer.WriteLine(String.Join(",", columnNames));
writer.Flush();
}
foreach (DataRow row in dtSource.Rows)
{
string[] fields = row.ItemArray.Select(field => "\"" + field.ToString().Replace("\"", "\"\"") + "\"").ToArray<string>();
writer.WriteLine(String.Join(",", fields));
writer.Flush();
}
return true;
}
As you can see, you can choose the output by initial StreamWriter, if you use
StreamWriter(Stream BaseStream), you can write csv into MemeryStream, FileStream, etc.
Origin
I have an easy datatable to csv function, it serves me well:
public static void DataTableToCsv(DataTable dt, string csvFile)
{
StringBuilder sb = new StringBuilder();
var columnNames = dt.Columns.Cast<DataColumn>().Select(column => "\"" + column.ColumnName.Replace("\"", "\"\"") + "\"").ToArray();
sb.AppendLine(string.Join(",", columnNames));
foreach (DataRow row in dt.Rows)
{
var fields = row.ItemArray.Select(field => "\"" + field.ToString().Replace("\"", "\"\"") + "\"").ToArray();
sb.AppendLine(string.Join(",", fields));
}
File.WriteAllText(csvFile, sb.ToString(), Encoding.Default);
}
If you can turn your datatable into an IEnumerable this should work for you...
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment;filename=FileName.csv");
Response.Charset = "";
Response.ContentType = "application/text";
Response.Output.Write(ExampleClass.ConvertToCSV(GetListOfObject(), typeof(object)));
Response.Flush();
Response.End();
public static string ConvertToCSV(IEnumerable col, Type type)
{
StringBuilder sb = new StringBuilder();
StringBuilder header = new StringBuilder();
// Gets all properies of the class
PropertyInfo[] pi = type.GetProperties();
// Create CSV header using the classes properties
foreach (PropertyInfo p in pi)
{
header.Append(p.Name + ",");
}
sb.AppendLine(header.ToString().Remove(header.Length));
foreach (object t in col)
{
StringBuilder body = new StringBuilder();
// Create new item
foreach (PropertyInfo p in pi)
{
object o = p.GetValue(t, null);
body.Append(o.ToString() + ",");
}
sb.AppendLine(body.ToString().Remove(body.Length));
}
return sb.ToString();
}
I don't know if this converted from VB to C# ok but if you don't want quotes around your numbers, you might compare the data type as follows..
public string DataTableToCSV(DataTable dt)
{
StringBuilder sb = new StringBuilder();
if (dt == null)
return "";
try {
// Create the header row
for (int i = 0; i <= dt.Columns.Count - 1; i++) {
// Append column name in quotes
sb.Append("\"" + dt.Columns[i].ColumnName + "\"");
// Add carriage return and linefeed if last column, else add comma
sb.Append(i == dt.Columns.Count - 1 ? "\n" : ",");
}
foreach (DataRow row in dt.Rows) {
for (int i = 0; i <= dt.Columns.Count - 1; i++) {
// Append value in quotes
//sb.Append("""" & row.Item(i) & """")
// OR only quote items that that are equivilant to strings
sb.Append(object.ReferenceEquals(dt.Columns[i].DataType, typeof(string)) || object.ReferenceEquals(dt.Columns[i].DataType, typeof(char)) ? "\"" + row[i] + "\"" : row[i]);
// Append CR+LF if last field, else add Comma
sb.Append(i == dt.Columns.Count - 1 ? "\n" : ",");
}
}
return sb.ToString;
} catch (Exception ex) {
// Handle the exception however you want
return "";
}
}
If you wish to stream the CSV out to the user without creating a file then I found the following to be the simplest method. You can use any extension/method to create the ToCsv() function (which returns a string based on the given DataTable).
var report = myDataTable.ToCsv();
var bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(report);
Response.Buffer = true;
Response.Clear();
Response.AddHeader("content-disposition", "attachment; filename=report.csv");
Response.ContentType = "text/csv";
Response.BinaryWrite(bytes);
Response.End();
I've used the following code, pillaged from someone's blog (pls forgive lack of citation). It takes care of quotations, newline and comma in a reasonably elegant way by quoting out each field value.
/// <summary>
/// Converts the passed in data table to a CSV-style string.
/// </summary>
/// <param name="table">Table to convert</param>
/// <returns>Resulting CSV-style string</returns>
public static string ToCSV(this DataTable table)
{
return ToCSV(table, ",", true);
}
/// <summary>
/// Converts the passed in data table to a CSV-style string.
/// </summary>
/// <param name="table">Table to convert</param>
/// <param name="includeHeader">true - include headers<br/>
/// false - do not include header column</param>
/// <returns>Resulting CSV-style string</returns>
public static string ToCSV(this DataTable table, bool includeHeader)
{
return ToCSV(table, ",", includeHeader);
}
/// <summary>
/// Converts the passed in data table to a CSV-style string.
/// </summary>
/// <param name="table">Table to convert</param>
/// <param name="includeHeader">true - include headers<br/>
/// false - do not include header column</param>
/// <returns>Resulting CSV-style string</returns>
public static string ToCSV(this DataTable table, string delimiter, bool includeHeader)
{
var result = new StringBuilder();
if (includeHeader)
{
foreach (DataColumn column in table.Columns)
{
result.Append(column.ColumnName);
result.Append(delimiter);
}
result.Remove(--result.Length, 0);
result.Append(Environment.NewLine);
}
foreach (DataRow row in table.Rows)
{
foreach (object item in row.ItemArray)
{
if (item is DBNull)
result.Append(delimiter);
else
{
string itemAsString = item.ToString();
// Double up all embedded double quotes
itemAsString = itemAsString.Replace("\"", "\"\"");
// To keep things simple, always delimit with double-quotes
// so we don't have to determine in which cases they're necessary
// and which cases they're not.
itemAsString = "\"" + itemAsString + "\"";
result.Append(itemAsString + delimiter);
}
}
result.Remove(--result.Length, 0);
result.Append(Environment.NewLine);
}
return result.ToString();
}
You can try using something like this.
In this case I used one stored procedure to get more data tables and export all of them
using CSV.
using System;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.IO;
namespace bo
{
class Program
{
static private void CreateCSVFile(DataTable dt, string strFilePath)
{
#region Export Grid to CSV
// Create the CSV file to which grid data will be exported.
StreamWriter sw = new StreamWriter(strFilePath, false);
int iColCount = dt.Columns.Count;
// First we will write the headers.
//DataTable dt = m_dsProducts.Tables[0];
for (int i = 0; i < iColCount; i++)
{
sw.Write(dt.Columns[i]);
if (i < iColCount - 1)
{
sw.Write(";");
}
}
sw.Write(sw.NewLine);
// Now write all the rows.
foreach (DataRow dr in dt.Rows)
{
for (int i = 0; i < iColCount; i++)
{
if (!Convert.IsDBNull(dr[i]))
{
sw.Write(dr[i].ToString());
}
if (i < iColCount -1 )
{
sw.Write(";");
}
}
sw.Write(sw.NewLine);
}
sw.Close();
#endregion
}
static void Main(string[] args)
{
string strConn = "connection string to sql";
string direktorij = #"d:";
SqlConnection conn = new SqlConnection(strConn);
SqlCommand command = new SqlCommand("sp_ado_pos_data", conn);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add('#skl_id', SqlDbType.Int).Value = 158;
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataSet ds = new DataSet();
adapter.Fill(ds);
for (int i = 0; i < ds.Tables.Count; i++)
{
string datoteka = (string.Format(#"{0}tablea{1}.csv", direktorij, i));
DataTable tabela = ds.Tables[i];
CreateCSVFile(tabela,datoteka );
Console.WriteLine("GeneriĊĦem tabelu {0}", datoteka);
}
Console.ReadKey();
}
}
}
public void CreateCSVFile(DataTable dt, string strFilePath,string separator)
{
#region Export Grid to CSV
// Create the CSV file to which grid data will be exported.
StreamWriter sw = new StreamWriter(strFilePath, false);
int iColCount = dt.Columns.Count;
for (int i = 0; i < iColCount; i++)
{
sw.Write(dt.Columns[i]);
if (i < iColCount - 1)
{
sw.Write(separator);
}
}
sw.Write(sw.NewLine);
// Now write all the rows.
foreach (DataRow dr in dt.Rows)
{
for (int i = 0; i < iColCount; i++)
{
if (!Convert.IsDBNull(dr[i]))
{
sw.Write(dr[i].ToString());
}
if (i < iColCount - 1)
{
sw.Write(separator);
}
}
sw.Write(sw.NewLine);
}
sw.Close();
#endregion
}
BFree's answer worked for me. I needed to post the stream right to the browser. Which I'd imagine is a common alternative. I added the following to BFree's Main() code to do this:
//StreamReader reader = new StreamReader(stream);
//Console.WriteLine(reader.ReadToEnd());
string fileName = "fileName.csv";
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment;filename={0}", fileName));
stream.Position = 0;
stream.WriteTo(HttpContext.Current.Response.OutputStream);