I use next code to export data from datagridView into xls file.
private void ToCsV(DataGridView dGv, string filename)
{
var stOutput = "";
// Export titles:
var sHeaders = "";
for (var j = 0; j < dGv.Columns.Count; j++)
sHeaders = sHeaders + Convert.ToString(dGv.Columns[j].HeaderText) + "\t";
stOutput += sHeaders + "\r\n";
// Export data.
for (var i = 0; i < dGv.RowCount - 1; i++)
{
var stLine = "";
for (var j = 0; j < dGv.Rows[i].Cells.Count; j++)
stLine = stLine + Convert.ToString(dGv.Rows[i].Cells[j].Value) + "\t";
stOutput += stLine + "\r\n";
}
var utf16 = Encoding.GetEncoding(1254);
byte[] output = utf16.GetBytes(stOutput);
var fs = new FileStream(filename, FileMode.Create);
var bw = new BinaryWriter(fs);
bw.Write(output, 0, output.Length); //write the encoded file
bw.Flush();
bw.Close();
fs.Close();
}
As result i get "bad" formated file :
I don't know why file content is like this (some text aren't in right columns). Any suggestion? Thanks.
Is it possible because some text for cell has "newLine" \n ?
Enclose all your values (or at least the ones being a potential issue) with double quotes. Instead of 123\n put "123\n" in your csv file.
This issue is most of the time encountered when using decimal separator in csv files, like explained here. Your \n case looks a lot alike.
Related
I have the below code that i m reading from datagrid and i export to ascii file and work fine
FileInfo info = new FileInfo(#"C:\SqlExports\");
info.Directory.Create();
string fileName = condition + " " + date + ".txt";
FileStream stream = new FileStream(#"C:\SqlExports\" + fileName, FileMode.OpenOrCreate);
StreamWriter sw = new StreamWriter(stream, Encoding.Default);
for (int i = 0; i < Grid.Rows.Count; i++)
{
List<string> rowprint = new List<string>();
for (int f = 0; f < Grid.Columns.Count; f++)
{
if (Grid.Rows[i].Cells[f].Value != DBNull.Value)
{ rowprint.Add(Grid.Rows[i].Cells[f].Value.ToString()); }
else
{
rowprint.Add(" ");
}
}
sw.Write(string.Format("{0,-19}", rowprint[0]) + String.Format("{0,10}", rowprint[1]) + sw.NewLine, Encoding.Default);
}
sw.Close();
I need to make my code reusable so if the grid populated with other datas to read each time what i need.
i tried
sw.Write(string.Format("0, -(rowprint[0].length + 2)", rowprint[0]) + string.Format("{"0,rowprint[1].Length + 2"} + sw.Newlinn, Encoding.Default);
but of course not working so how can i have the length plus 2 blanks and the value?
of course i know that i need a var with the columns because its time maybe the columns is 2 or 3 or etc.
System.IndexOutOfRangeException: Index was outside the bounds of the array.
How to solve this error ?
Can anyone know this ?
Below my coding... when execute it produce the error that
System.IndexOutOfRangeException Index was outside the bounds of the array
, only if tried to process this csv file :
Instead I don't have error if tried to process this csv file :
Excel.IExcelDataReader excelReader = Excel.ExcelReaderFactory.CreateBinaryReader(stream);
DataSet result = excelReader.AsDataSet();
excelReader.Close();
result.Tables[0].TableName.ToString();
string csvData = "";
int row_no = 0;
int ind = 0;
while (row_no < result.Tables[ind].Rows.Count)
{
for (int i = 0; i < result.Tables[ind].Columns.Count; i++)
{
csvData += result.Tables[ind].Rows[row_no][i].ToString() + "|";
}
row_no++;
csvData += "\n";
}
keys = GetUniqueKey(12).ToUpper();
output = System.Web.HttpContext.Current.Server.MapPath("/public/" + keys.ToString() + ".csv");
StreamWriter csv = new StreamWriter(#output, false);
csv.Write(csvData);
csv.Close();
csv.Dispose();
string toCheck;
using (var fs = new FileStream(output, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var sr = new StreamReader(fs, Encoding.Default))
{
toCheck = sr.ReadToEnd();
if (toCheck.Contains("ColumnAAA") == false)
{
////Start add new column
int posNewColumn = 2;
string[] CSVDump = File.ReadAllLines(output);
List<List<string>> CSV = CSVDump.Select(x => x.Split('|').ToList()).ToList();
for (int i = 0; i < CSV.Count; i++)
{
if (CSV[i].Count > posNewColumn)
{
CSV[i].Insert(posNewColumn, i == 0 ? "ColumnAAA" : "ColumnAAA");
}
else
{
CSV[i].Add(i == 0 ? "ColumnAAA" : "ColumnAAA");
}
}
File.WriteAllLines(output, CSV.Select(x => string.Join("|", x)));
sr.Close();
////End add new column
}
}
Edit #01
The problem is in this line of code-behind.
The code print correctly the number of rows, but I have error when try print and Split the number of columns :
lines = File.ReadAllLines(System.Web.HttpContext.Current.Server.MapPath("/public/" + keys.ToString() + ".csv"));
rows = lines.Count();
columns = lines[23].Split('|').Count();
Response.Write("Number of rows/columns = " + rows.ToString() + "/" + columns.ToString());
Response.End();
Try this :
lines = File.ReadAllLines(System.Web.HttpContext.Current.Server.MapPath("/public/" + keys.ToString() + ".csv"));
rows = lines.Count();
int i = 0;
foreach (string line in lines)
{
string[] parts = line.Split('|');
foreach (string part in parts)
{
columns = parts.Count();
}
i++;
}
Response.Write("Number of rows/columns = " + rows.ToString() + "/" + columns.ToString());
Response.End();
As input, I have a set of excel files with several worksheets inside. I need to export a single csv file for each worksheet. Below is my code which works but it is very slow. It builds upon the solutions proposed in this previous post. Please consider that I have to run this on rather big .xlsx files (approx. 300Mb).
QUESTION: Is there any way to improve this?
void Main()
{
string folder = #"\\PATH_TO_FOLDER\";
var files = Directory.GetFiles(folder, "*.xlsx", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
ConvertToCsv(file, Directory.GetParent(file) + #"\\output\");
}
}
public static void ConvertToCsv(string file, string targetFolder)
{
FileInfo finfo = new FileInfo(file);
ExcelPackage package = new ExcelPackage(finfo);
// if targetFolder doesn't exist, create it
if (!Directory.Exists(targetFolder)) {
Directory.CreateDirectory(targetFolder);
}
var worksheets = package.Workbook.Worksheets;
int sheetcount = 0;
foreach (ExcelWorksheet worksheet in worksheets)
{
sheetcount++;
var maxColumnNumber = worksheet.Dimension.End.Column;
var currentRow = new List<string>(maxColumnNumber);
var totalRowCount = worksheet.Dimension.End.Row+1;
var currentRowNum = 1;
//No need for a memory buffer, writing directly to a file
//var memory = new MemoryStream();
string file_name = targetFolder + Path.GetFileNameWithoutExtension(file) + "_" + sheetcount + ".csv";
using (var writer = new StreamWriter(file_name, false, Encoding.UTF8))
{
//the rest of the code remains the same
for (int i = 1; i < totalRowCount; i++)
{
i.Dump();
// populate line with semi columns separators
string line = "";
for (int j = 1; j < worksheet.Dimension.End.Column+1; j++)
{
if (worksheet.Cells[i, j].Value != null)
{
string cell = worksheet.Cells[i, j].Value.ToString() + ";";
line += cell;
}
}
// write line
writer.WriteLine(line);
}
}
}
}
I have the code below to save data into a excel file(.csv).
private void SavedataToolStripMenuItem_Click(object sender, EventArgs e)
{
now_status.Text = "save data to excel";
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{[![enter image description here][1]][1]
selectedFileName = saveFileDialog1.FileName + ".csv";
System.Text.Encoding enc = System.Text.Encoding.GetEncoding("Shift_JIS");
System.IO.StreamWriter sr = new System.IO.StreamWriter(selectedFileName, false, enc);
int rowCountA = int.Parse(objA_n.Text);
int rowCountB = int.Parse(objB_n.Text);
string field;
field = "Saved Data" + "\r\n" + "Numb,Time(S),AX,AY,BX,BY" + "\r\n";
sr.Write(field);
for (int i = 1; i < rowCountA + 1; i++)
{
string fieldA;
fieldA = "A" + dn_objA[i].ToString() + "," + dtime_objA[i].ToString() + "," + dx_objA[i].ToString() + "," + dy_objA[i].ToString() + ",," + "\r\n";
sr.Write(fieldA);
}
for (int i = 1; i < rowCountB + 1; i++)
{
string fieldB;
fieldB = "B" + dn_objB[i].ToString() + "," + dtime_objB[i].ToString() + ",,," + dx_objB[i].ToString() + "," + dy_objB[i].ToString() + "\r\n";
sr.Write(fieldB);
}
sr.Close();
sr.Close();
}
}
This Generates a simple excel file like this below. Object values will be inserted below the second row.
Is there a way to do the same thing, but into a template excel file? I have an excel file like the one below.
I would like the imported data to show on the left hand side of the excel file.
Also, I want to use macros that I made in the second excel file shown.
Can you say me, how can i save the contents of DataGridView to Exel File with the Formatting cells Backcolor/Forecolor? I have DGV like this:
And when I try to Export Data to Excel I get the data, but without Forecolor, I have tried a several of ways, but it does not work! Beforehand Thank you!
private void btnExport_Click(object sender, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Excel Documents (*.xls)|*.xls";
sfd.FileName = "export.xls";
if (sfd.ShowDialog() == DialogResult.OK)
{
//ToCsV(dataGridView1, #"c:\export.xls");
ToCsV1(dataGridView1, sfd.FileName);
}
}
private void ToCsV1(DataGridView dGV, string filename)
{
string stOutput = "";
// Export titles:
string sHeaders = "";
for (int j = 0; j < dGV.Columns.Count; j++)
sHeaders = sHeaders.ToString() + Convert.ToString(dGV.Columns[j].HeaderText) + "\t";
stOutput += sHeaders + "\r\n";
// Export data.
for (int i = 0; i < dGV.RowCount - 1; i++)
{
string stLine = "";
for (int j = 0; j < dGV.Rows[i].Cells.Count; j++)
stLine = stLine.ToString() + Convert.ToString(dGV.Rows[i].Cells[j].Value) + "\t";
stOutput += stLine + "\r\n";
}
Encoding utf16 = Encoding.GetEncoding(1254);
byte[] output = utf16.GetBytes(stOutput);
FileStream fs = new FileStream(filename, FileMode.Create);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(output, 0, output.Length); //write the encoded file
bw.Flush();
bw.Close();
fs.Close();
}
try to export to ExcelXML
Example:
using (var writer = new StreamWriter(fileDialog.OpenFile(), Encoding.UTF8))
{
if (format == "XML")
{
writer.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
writer.WriteLine("<?mso-application progid=\"Excel.Sheet\"?>");
writer.WriteLine("<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\">");
writer.WriteLine("<DocumentProperties xmlns=\"urn:schemas-microsoft-com:office:office\">");
writer.WriteLine("<Author></Author>");
writer.WriteLine("<Created>" + DateTime.Now.ToLocalTime().ToLongDateString() + "</Created>");
writer.WriteLine("<LastSaved>" + DateTime.Now.ToLocalTime().ToLongDateString() + "</LastSaved>");
writer.WriteLine("<Company></Company>");
writer.WriteLine("<Version>12.00</Version>");
writer.WriteLine("</DocumentProperties>");
if (showGroupHeaders)
AddStyles(writer, groupDesc.Count());
writer.WriteLine(
"<Worksheet ss:Name=\"Silverlight Export\" xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\">");
writer.WriteLine("<Table>");
}
writer.Write(text.ToString());
if (format == "XML")
{
writer.WriteLine("</Table>");
writer.WriteLine("</Worksheet>");
writer.WriteLine("</Workbook>");
}
writer.Close();
}
Where AddStyle Like this:
private static void AddStyles(StreamWriter writer, int groupCount)
{
writer.WriteLine("<Styles>");
for (int i = 0; i < groupCount; i++)
{
int shift = i % _headerColor.Count();
var color = _headerColor[shift];
writer.WriteLine("<Style ss:ID=\"st{0}\">", i + 1);
writer.WriteLine("<Interior ss:Color=\"#{0:X2}{1:X2}{2:X2}\" ss:Pattern=\"Solid\"/>", color.R, color.G, color.B);
writer.WriteLine("</Style>");
}
writer.WriteLine("</Styles>");
}
And Set cell backcolor:
string.Format("<Cell ss:StyleID=\"st{0}\"><Data ss:Type=\"String\">{1}</Data></Cell>", style, data);
Here is an example using GemBox.Spreadsheet component to work with Excel files and cell formatting.