NPOI AutoSizeColumn not resizing correctly - c#

I've put the .AutoSizeColumn right before the write Method
int numberOfColumns = sheet.GetRow(rowcount - 1).PhysicalNumberOfCells;
for (int i = 0; i <= numberOfColumns; i++)
{
sheet.AutoSizeColumn(i);
GC.Collect();
}
using (var fileData = new FileStream(#"C:\Temp\Contatti.xlsx", FileMode.Create))
{
wb.Write(fileData);
}
this is an example of the result

The problem also migh be, that PhysicalNumberOfCells can return 1, even if you have a cell lets say in 'Z' column. There is LastCellNum property,you i instead of PhysicalNumberOfCells:
int lastColumNum = sheet.GetRow(0).LastCellNum;
for (int i = 0; i <= lastColumNum; i++)
{
sheet.AutoSizeColumn(i);
GC.Collect();
}
using (var fileData = new FileStream(#"D:\Contatti.xlsx", FileMode.Create))
{
wb.Write(fileData);
}

Related

StreamWriter writes all data into obe Column in CSV

using (var stream = new MemoryStream())
using (var writer = new StreamWriter(stream))
using (var mailClient = client)
using (var messagesd = msg)
{
foreach (DataColumn column in objDT.Columns)
{
writer.WriteLine(column.ColumnName);
}
writer.WriteLine();
for (int i = 0; i < objDT.Rows.Count; i++)
{
DataRow row = objDT.Rows[i];
for (int j = 0; j < row.ItemArray.Length; j++)
{
if (row.ItemArray[j] != null && !Convert.IsDBNull(row.ItemArray[j]))
{
writer.Write(row.ItemArray[j].ToString());
}
else
{
writer.Write("");
}
if (j < row.ItemArray.Length - 1)
{
writer.Write(",");
}
else if (i < objDT.Rows.Count - 1)
{
writer.WriteLine();
}
}
}
writer.Flush();
stream.Position = 0;
messagesd.Attachments.Add(new Attachment(stream, "test.csv"));
mailClient.Send(messagesd);
I have 3 columns, but result I`m getting:
testATestBTestC
under single column
Result i want is TestA column 1, TestB column 2 and TestC column 3
Any help would be appreciated. Thank you.
You should write a delimeter(,) after every value (header name or value) except last one. Use Writemethod to put values into a row and WriteLine to start a new row.
It is better to use existing libraries from Nuget. CSVHelperas example.

OutOfMemory while adding pictures to Excel Sheet

I have problem with memory.
I want do add pictures to my excel. Picuters are on azure blob.
After 1k of added pictures my program slowing so much till outofmemory exception.
I will paste my code here:
string filePath = #"excel.xlsx";
int i = 0;
public void Generate(int worksheetnumber)
{
using (FileStream fileStream = File.Open(filePath, FileMode.Open))
{
var package = new ExcelPackage(fileStream);
ExcelWorksheet workSheet = package.Workbook.Worksheets[worksheetnumber];
workSheet.Column(2).Width = 21;
workSheet.Column(4).Width = 21;
for (int j = workSheet.Dimension.Start.Row + 1; j <= workSheet.Dimension.End.Row; j++)
{
InsertImage(workSheet, j, 1);
InsertImage(workSheet, j, 3);
}
string path = string.Format(#"{0}.xlsx", worksheetnumber);
Stream stream2 = File.Create(path);
package.SaveAs(stream2);
stream2.Close();
}
}
private void InsertImage(ExcelWorksheet workSheet, int j, int columnNumber)
{
if (!string.IsNullOrEmpty(workSheet.Cells[j, columnNumber].Text))
{
try
{
var splittedUrlHash = workSheet.Cells[j, columnNumber].Text.Split('/');
using (var stream = DownloadBlobFileToStream(splittedUrlHash[1], splittedUrlHash[0], SHOP))
{
Image image = Image.FromStream(stream);
var picture = workSheet.Drawings.AddPicture(string.Format("{0}{1}", j, columnNumber+1), image);
stream.Close();
picture.From.Column = columnNumber;
picture.From.Row = j - 1;
picture.To.Column = columnNumber;
picture.To.Row = j - 1;
picture.SetSize(150, 120);
workSheet.Row(j).Height = 100;
Debug.WriteLine("Dodano obrazek - {0}", i);
i++;
}
}
catch (System.ArgumentException e)
{
}
}
}
I want to admit, I have a link images in Columns 1 and 3. Images are locating in cols 2 and 4.
Is there any solution to handle this error in this case without losing images, or leaving empty cells

C# Working with excel file

After save changes from dataGridView,when open xlsx file by excel this error occurs:
We found a problem with some content in 'Book1.xlsx' Do you want us to recover as much as we can? If you trust the source of this workbook, click Yes.
for (int i = 0; i < dataGridView1.RowCount - 1; i++)
{
if (sh.GetRow(i) == null)
sh.CreateRow(i);
for (int j = 0; j < dataGridView1.ColumnCount; j++)
{
if (sh.GetRow(i).GetCell(j) == null)
sh.GetRow(i).CreateCell(j);
if (dataGridView1[j, i].Value != null)
{
sh.GetRow(i).GetCell(j).SetCellValue(dataGridView1[j, i].Value.ToString());
}
using (var fs = new FileStream("Book1.xlsx", FileMode.Open, FileAccess.ReadWrite))
{
wb.Write(fs);
}
}
}
For one thing, you're writing the workbook multiple times, once for each cell. You really should only write the workbook once, at the end, when you are finished making changes.
Also, it is not clear from your question how you are creating the workbook or the sheet. I added some code below to make it clear how that should look as well.
Try it like this:
XSSFWorkbook wb = new XSSFWorkbook();
ISheet sheet = wb.GetSheet("Sheet1") ?? wb.CreateSheet("Sheet1");
for (int i = 0; i < dataGridView1.RowCount; i++)
{
IRow row = sheet.GetRow(i) ?? sh.CreateRow(i);
for (int j = 0; j < dataGridView1.ColumnCount; j++)
{
ICell cell = row.GetCell(j) ?? row.CreateCell(j);
if (dataGridView1[j, i].Value != null)
{
cell.SetCellValue(dataGridView1[j, i].Value.ToString());
}
}
}
using (var fs = new FileStream("Book1.xlsx", FileMode.Create, FileAccess.Write))
{
wb.Write(fs);
}

How to Export DataSet to notepad?

how to Export DataSet(multiple of Datatables) to a notepad. From c#
Note: NOT A SINGLE DataTable ,Multiple DataTables From DataSet;
I would suggest something simple, create a translator or download a bunch of other libraries available on the web.
you would most like go
public interfacte IExport
{
bool Export(Databale sometable);// this can also reference interface
//concrete implementation could also handle saving of file
}
then call on a concrete class to implement that value, use a Factory Patter, Dependency Injection, etc to supply the concrete type. Then you can keep adding as many converters to support as many file types as you'd like.
private void Write(System.Data.DataSet dts, string outputFilePath)
{
System.Data.DataTable dt = new System.Data.DataTable();
for (int z = 0; z < dts.Tables.Count; z++)
{
dt = dts.Tables[z];
int[] maxLengths = new int[dt.Columns.Count];
for (int i = 0; i < dt.Columns.Count; i++)
{
maxLengths[i] = dt.Columns[i].ColumnName.Length;
foreach (DataRow row in dt.Rows)
{
if (!row.IsNull(i))
{
int length = row[i].ToString().Length;
if (length > maxLengths[i])
{
maxLengths[i] = length;
}
}
}
}
using (StreamWriter sw = new StreamWriter(outputFilePath, true))
{
for (int i = 0; i < dt.Columns.Count; i++)
{
sw.Write(dt.Columns[i].ColumnName.PadRight(maxLengths[i] + 2));
}
sw.WriteLine();
foreach (DataRow row in dt.Rows)
{
for (int i = 0; i < dt.Columns.Count; i++)
{
if (!row.IsNull(i))
{
sw.Write(row[i].ToString().PadRight(maxLengths[i] + 2));
}
else
{
sw.Write(new string(' ', maxLengths[i] + 2));
}
}
sw.WriteLine();
}
sw.Close();
}
}
}

My text file won't read and display on the DataGridView

private void write(object sender, EventArgs e)
{
FileStream outputFileStream = new FileStream("test.txt", FileMode.Create, FileAccess.Write);
StreamWriter writer = new StreamWriter(outputFileStream);
Random r = new Random();
for (int i = 0; i < dataGridView1.RowCount; i++)
{
for (int j = 0; j < dataGridView1.ColumnCount; j++)
{
double d = 0;
Double.TryParse(Convert.ToString(dataGridView1.Rows[i].Cells[j].Value), out d);
writer.Write(d + "\t");
}
writer.Write("\n");
}
writer.Close();
outputFileStream.Close();
}
So this is the method to write the text file. It works fine because I have opened it successfully with an Excel. I even tried to copy and paste it and it would work. Now the problem is.....
private void read(object sender, EventArgs e)
{
char TAB = '\t';
char NEWLINE = '\n';
FileStream inputFileStream = new FileStream("test.txt", FileMode.Open, FileAccess.Read);
StreamReader reader = new StreamReader(inputFileStream);
string line;
string[] fields;
for (int i = 0; i < dataGridView1.RowCount; i++)
{
for (int j = 0; j < dataGridView1.ColumnCount; j++)
{
line = reader.ReadLine();
fields = line.Split(TAB, NEWLINE);
dataGridView1.Rows[i].Cells[j].Value = fields;
}
}
inputFileStream.Close();
reader.Close();
}
However when I read the file back onto a DataGridView it does not work properly. Now this is the exact text file that I wrote on my code. Instead what happens is that it is displayed on only 1 row. How do I get back the amount of columns and rows from what the user entered? I prefer keeping it a text file.
I have used default properties for my dataGridView1
RowCount returns displayed rows count. So here it returns 1 because you are displaying one row and it's empty:
for (int i = 0; i < dataGridView1.RowCount; i++)
Instead of this, you should create new rows and add it to the Rows collection like this:
// Use File.ReadAllLines, it's easier
string[] lines = File.ReadAllLines("test.txt");
foreach(line in lines)
{
var text = line.Split('\t','\n');
dataGridView1.Rows.Add(text);
}
System.IO.StreamReader file = new System.IO.StreamReader("yourfile.txt");
string[] columnnames = file.ReadLine().Split(' ');
DataTable dt = new DataTable();
foreach (string c in columnnames)
{
dt.Columns.Add(c);
}
string newline;
while ((newline = file.ReadLine()) != null)
{
DataRow dr = dt.NewRow();
string[] values = newline.Split(' ');
for (int i = 0; i < values.Length; i++)
{
dr[i] = values[i];
}
dt.Rows.Add(dr);
}
file.Close();
dataGridView1.DataSource = dt;
try this one with your own delimiters i.e. \t and \n. And First try to search your problems on internet before posting queries and try to solve them by yourself. I am not giving full code.

Categories

Resources