Random memory leak while reading xlsx files using C# - c#

I am new to C# and wpf but am trying to read a lot of data (abt. 40000 x 34 cells) from +100 xlsx files and concatenate them into a text file.
I have made a small C# (wpf) app to do that. I see somewhat random memory leak, where sometimes as I run it, everything goes well and the memory it requires (according to windows task manager) stays under 1 GB, while other times it eats, almost all of my 8 GB.
One situation I have found happens when using System.IO.File.ReadAllLines(pathtotextfilewithxlsxfilenames)
whereas using the discreet example (specifying the filenames in the code) does not in the same way seem to cause the problem. (I have copied and pasted the same names from the text file with xlsx-filenames to the code (replaced tabs with ", ") so it should be equal.. as far as I understand).
The app is roughly like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data;
using System.IO;
using System.Data.OleDb;
namespace WpfApps
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
string s_path_to_list_of_xlsx_files;
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
string path = #"F:\...\xls_files\";
string[] fnlist = { "datafile1.xlsx", "datafile2.xlsx", ... "datafileN.xlsx" };
//string[] fnlist = System.IO.File.ReadAllLines(#"f:\...\xlsfiles.txt"); // It seems as if using this line, compared to the discreet line above causes memory leak.
DataTable measurementdata = new DataTable();
measurementdata.Columns.Add("C1", typeof(double));
measurementdata.Columns.Add("C2", typeof(double));
...
measurementdata.Columns.Add("C34", typeof(double));
using (StreamWriter sw = File.CreateText(path + "allresult.txt"))
{
bool firstCol = true;
foreach (DataColumn col in measurementdata.Columns)
{
if (!firstCol) sw.Write(", ");
sw.Write(col.ColumnName);
firstCol = false;
}
sw.WriteLine();
}
foreach (var fn in fnlist)
{
DataTable filedt = GetDataTableFromExcel(path + fn, false);
using (StreamWriter sw = File.AppendText(path + "allresult.txt"))
{
foreach (DataRow row in filedt.Rows)
{
bool firstCol = true;
foreach (DataColumn col in filedt.Columns)
{
if (!firstCol) sw.Write(", ");
sw.Write(row[col].ToString());
firstCol = false;
}
sw.WriteLine();
}
}
}
}
public static DataTable GetDataTableFromExcel(string path, bool hasHeader = true)
{
using (var pck = new OfficeOpenXml.ExcelPackage())
{
using (var stream = File.OpenRead(path))
{
pck.Load(stream);
}
var ws = pck.Workbook.Worksheets["Logged Data"];
int startrow = 72;
int endrow = 43271;
DataTable tbl = new DataTable();
foreach (var firstrowcell in ws.Cells[startrow - 1, 8, startrow - 1, 41])
{
tbl.Columns.Add(firstrowcell.Text);
}
for (int rowNum = startrow; rowNum <= endrow; rowNum++)
{
var wsRow = ws.Cells[rowNum, 8, rowNum, 41];
DataRow row = tbl.Rows.Add();
foreach (var cell in wsRow)
{
var cellvalue = cell.Value;
if (cellvalue == null) cellvalue = "0";
row[cell.Start.Column - 8] = cellvalue;
}
}
return tbl;
}
}
Can anyone see an obvious problem?

Related

Read the first 10 lines of a .txt file and print them in a DataTable with non-fixed number of columns C#

I am running the following C# code to read only the first 10 lines of a .txt file:
using MaterialDesignThemes.Wpf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Data;
namespace TestEnvironment
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void BrowseButton_Click(object sender, RoutedEventArgs e)
{
// Create OpenFileDialog
Microsoft.Win32.OpenFileDialog openFileDlg = new Microsoft.Win32.OpenFileDialog();
// Launch OpenFileDialog by calling ShowDialog method
Nullable<bool> result = openFileDlg.ShowDialog();
// Get the selected file name and display in a TextBox.
// Load content of file in a TextBlock
if (result == true)
{
FileNameTextBox.Text = openFileDlg.FileName;
TextBlock1.Text = "Created on: " + System.IO.File.GetCreationTime(openFileDlg.FileName).ToString();
TextBlock1.Text += Environment.NewLine + Environment.NewLine + string.Join("\r\n", System.IO.File.ReadLines(openFileDlg.FileName).Take(10));
//System.IO.File.ReadLines(openFileDlg.FileName).Take(10).ToString()
Debug.WriteLine("Txt file contents!");
}
// Set filter for file extension and default file extension
openFileDlg.DefaultExt = ".txt";
openFileDlg.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
Debug.WriteLine("Txt imported");
// Set initial directory
openFileDlg.InitialDirectory = #"C:\Documents\";
// Multiple selection with all file types
openFileDlg.Multiselect = true;
Debug.WriteLine("End!");
}
private void TabablzControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
}
}
Current output
But this what I want. I actually want to print the content in a table format, with column names and rows.
To do so I have searched for a similar question and found this. However, the answer posted there is using a fixed number of columns. But I want to make this method take a dynamic number of columns because my txt files don't have the same length of columns.
The code I run now:
using MaterialDesignThemes.Wpf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Data;
namespace TestEnvironment
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public DataTable ConvertToDataTable(string filePath, int numberOfColumns)
{
DataTable tbl = new DataTable();
for (int col = 0; col < numberOfColumns; col++)
tbl.Columns.Add(new DataColumn("Column" + (col + 1).ToString()));
string[] lines = System.IO.File.ReadAllLines(filePath);
var lines1 = lines.Take(10);
Debug.WriteLine(lines1);
foreach (string line in lines1)
{
var cols = line.Split('\t');
DataRow dr = tbl.NewRow();
for (int cIndex = 0; cIndex < line.Length; cIndex++)
{
dr[cIndex] = cols[cIndex];
}
tbl.Rows.Add(dr);
}
return tbl;
}
private void BrowseButton_Click(object sender, RoutedEventArgs e)
{
// Create OpenFileDialog
Microsoft.Win32.OpenFileDialog openFileDlg = new Microsoft.Win32.OpenFileDialog();
// Launch OpenFileDialog by calling ShowDialog method
Nullable<bool> result = openFileDlg.ShowDialog();
// Get the selected file name and display in a TextBox.
// Load content of file in a TextBlock
if (result == true)
{
FileNameTextBox.Text = openFileDlg.FileName;
TextBlock1.Text = "Created on: " + System.IO.File.GetCreationTime(openFileDlg.FileName).ToString();
var travelTime = ConvertToDataTable(filePath: openFileDlg.FileName, numberOfColumns: 1);
TextBlock1.Text += Environment.NewLine + Environment.NewLine + travelTime;
//TextBlock1.Text += Environment.NewLine + Environment.NewLine + string.Join("\r\n", System.IO.File.ReadLines(openFileDlg.FileName).Take(10));
//System.IO.File.ReadLines(openFileDlg.FileName).Take(10).ToString()
Debug.WriteLine("Txt file contents!");
}
// Set filter for file extension and default file extension
openFileDlg.DefaultExt = ".txt";
openFileDlg.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
Debug.WriteLine("Txt imported");
// Set initial directory
openFileDlg.InitialDirectory = #"C:\Documents\";
// Multiple selection with all file types
openFileDlg.Multiselect = true;
Debug.WriteLine("End!");
}
private void TabablzControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
}
}
I get the following error:
Thank you in advance for any comments and help. Happy to provide more info is something was not clear.
A dummy .txt file I created my self can be found here
[UPDATE] based on the comments
After running this: (credits to: gkulshrestha)
public DataTable ConvertToDataTable(string filePath)
{
DataTable tbl = new DataTable();
string[] lines = System.IO.File.ReadAllLines(filePath);
var lines1 = lines.Take(10);
for (int col = 0; col < lines1.First().Split('\t').Length; col++)
tbl.Columns.Add(new DataColumn("Column" + (col + 1).ToString()));
foreach (string line in lines1)
{
var cols = line.Split('\t');
DataRow dr = tbl.NewRow();
for (int cIndex = 0; cIndex < cols.Length; cIndex++)
{
dr[cIndex] = cols[cIndex];
}
tbl.Rows.Add(dr);
}
return tbl;
}
if (result == true)
{
FileNameTextBox.Text = openFileDlg.FileName;
TextBlock1.Text = "Created on: " + System.IO.File.GetCreationTime(openFileDlg.FileName).ToString();
TextBlock1.Text += Environment.NewLine + Environment.NewLine + ConvertToDataTable(filePath: openFileDlg.FileName);
//TextBlock1.Text += Environment.NewLine + Environment.NewLine + string.Join("\r\n", System.IO.File.ReadLines(openFileDlg.FileName).Take(10));
//System.IO.File.ReadLines(openFileDlg.FileName).Take(10).ToString()
Debug.WriteLine("Txt file contents!");
}
I get nothing in return but only the created on Date which is the first Text of my TextBox
[UPDATE 2: Need for encoding the Row.Add content to UTF-8]
I am trying to encode the content of the Row.Add() into UTF-8. Now its ANSI. Searching online I came across online articles.
So my DataGrid table method looks like:
public DataTable ConvertToDataTable(string filePath)
{
DataTable tbl = new DataTable();
// Take the first 10 lines
var lines = File.ReadLines(filePath).Take(10);
// Split each line and create an integer sequence where each value
// is the number of the splitted elements
// then get the max value present in this sequence
var max = lines.Select(x => x.Split('\t').Length).Max();
// First line contains headers
string[] headers = lines.First().Split('\t');
// Now create the table with the max number of columns present
for (int col = 0; col < max; col++)
tbl.Columns.Add(new DataColumn(headers[col]));
//Use the Rows.Add method that accepts an object array
foreach (string line in lines.Skip(1))
{
//tbl.Rows.Add(line.Split('\t'));
var utf8 = Encoding.UTF8;
byte[] utfBytes = utf8.GetBytes(tbl.Rows.Add(line.Split('\t')));
var myReturnedString = utf8.GetString(utfBytes);
tbl.Rows.Add(myReturnedString);
}
foreach (DataRow dr in tbl.Rows)
{
Debug.WriteLine(dr["Nationality"]);
string s = dr["Nationality"].ToString();
byte[] bytes = Encoding.Default.GetBytes(s);
dr["Nationality"] = Encoding.UTF8.GetString(bytes);
Debug.WriteLine(dr["Nationality"]);
}
return tbl;
}
But inside the Row.Add() method I get an error:
Cannot convert from 'System.Data.DataRow' to 'char[]'
The error message tells you that one of your lines has more columns than the value passed in the numberOfColumns variable. So you build a table with a certain number of columns but then you find a line with more data.
You can simply change the check for the exit condition on the for loop
for (int cIndex = 0; cIndex < cols.Length && cIndex < numberOfColumns; cIndex++)
However this will simply ignore the extra data. You should understand why a line has more data and decide if you want to keep that extra or not.
In case you don't know beforehand the number of columns present in your file, then you can change the ConvertToDataTable and allow it to discover the max number of columns (Always keep in mind that with 10 lines there is no performace problem, but with large files things change)
// No need to pass the number of columns, let the method discover it
public DataTable ConvertToDataTable(string filePath)
{
DataTable tbl = new DataTable();
// Take the first 10 lines
var lines = File.ReadLines(filePath).Take(10);
// Split each line and create an integer sequence where each value
// is the number of the splitted elements
// then get the max value present in this sequence
var max = lines.Select(x => x.Split('\t').Length).Max();
// First line contains headers
string[] headers = lines.First().Split('\t');
// Now create the table with the max number of columns present
for (int col = 0; col < max; col++)
tbl.Columns.Add(new DataColumn(headers[col]));
// You can simplify a lot your loop using the Rows.Add method that
// accepts an object array
foreach (string line in lines.Skip(1))
{
tbl.Rows.Add(line.Split('\t'));
}
return tbl;
}
Since you do not know before hand the number of columns your text file will have, you cannot pass numberOfColumns to ConvertToDataTable function.
Better you determine the column count inside the function itself after file has been read.
Try this:
public DataTable ConvertToDataTable(string filePath)
{
DataTable tbl = new DataTable();
string[] lines = System.IO.File.ReadAllLines(filePath);
var lines1 = lines.Take(10);
for (int col = 0; col < lines1.First().Split('\t').Length; col++)
tbl.Columns.Add(new DataColumn("Column" + (col + 1).ToString()));
foreach (string line in lines1)
{
var cols = line.Split('\t');
DataRow dr = tbl.NewRow();
for (int cIndex = 0; cIndex < cols.Length; cIndex++)
{
dr[cIndex] = cols[cIndex];
}
tbl.Rows.Add(dr);
}
return tbl;
}
For a such a case you can use
public DataTable ConvertToDataTable(string filePath)
{
DataTable tbl = new DataTable();
string[] lines = System.IO.File.ReadAllLines(filePath);
// just use lines.Take(10) if you want only 10 lines
for (int col = 0; col < lines.First().Split('\t').Length; col++)
tbl.Columns.Add(new DataColumn("Column" + (col + 1).ToString()));
foreach (string line in lines)
{
var cols = line.Split('\t');
DataRow dr = tbl.NewRow();
for (int cIndex = 0; cIndex < cols.Length; cIndex++)
{
dr[cIndex] = cols[cIndex];
}
tbl.Rows.Add(dr);
}
return tbl;
}

How to remove the top rows of an Excel Spreadsheet on Import to a SQL Server Database

Hello Stack Overflow community. I'm writing a small application in C# that can import an excel file directly into a SQL Database. I can import files with the current headers that are in the Excel File as they match the column names (See 2nd Image link below) in my Database, however I am looking to add some flexibility to the excel files that I can Import. Ex: Some of the excel files i need to import have a legend at the top, and this legend does not match the column headers in my database (See 1st image link)
In this Image you can see the portion of the excel sheet I want to remove with code
The Files that do not contain that Legend at the top are easily imported
Without the legend this is where the import can occur at line row 10 in the excel file
I'm looking for a way to remove the top 9 rows (The legend at the top of the file) on import.
Here is all the source code. Any help would be greatly appreciated.
using ExcelDataReader;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Data.OleDb;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ProviderBreakfastExcelReader
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void BtnOpen_Click(object sender, EventArgs e)
{
using (OpenFileDialog ofd = new OpenFileDialog() { Filter = "Excel Workbook|*.xlsx", ValidateNames = true })
{
if (ofd.ShowDialog() == DialogResult.OK)
{
var ExcelData = ExcelFileRead(ofd.FileName);
cboSheet.Items.Clear();
foreach (DataTable dt in ExcelData.Tables)
{
cboSheet.Items.Add(dt.TableName);
}
}
}
}
private void CboSheet_SelectedIndexChanged(object sender, EventArgs e)
{
string path = #"C:\Desktop\Dir\filename.xlsx";
FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read);
IExcelDataReader reader = ExcelReaderFactory.CreateOpenXmlReader(stream);
DataSet result = reader.AsDataSet();
dataGridView.DataSource = result.Tables[cboSheet.SelectedIndex];
}
private DataSet ExcelFileRead(string path)
{
using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read))
using (IExcelDataReader reader = ExcelReaderFactory.CreateOpenXmlReader(fs))
{
var result = reader.AsDataSet(new ExcelDataSetConfiguration()
{
UseColumnDataType = true,
ConfigureDataTable = (_) => new ExcelDataTableConfiguration()
{
EmptyColumnNamePrefix = "Column",
UseHeaderRow = true,
}
});
return result;
}
}
private void SendExcelToDatabase(string Filename)
{
var data = ExcelFileRead(Filename);
using (var db = new ProviderBreakfastDBEntities())
{
foreach (DataRow record in data.Tables[0].Rows)
{
int rank;
var isValidRank = int.TryParse(record["Ranking"].ToString(), out rank);
db.ProviderBreakfastExcels.Add(new ProviderBreakfastExcel
{
Ranking = isValidRank ? rank : new int?(),
Contact = record["Contact"].ToString(),
LastName = record["LastName"].ToString(),
FirstName = record["FirstName"].ToString(),
// Bedsize = isValidBedsize ? beds : new int?(),
Bedsize = Convert.ToInt32(record["Bedsize"].ToString()),
City = record["City"].ToString(),
Company = record["Company"].ToString(),
JobTitle = record["JobTitle"].ToString(),
State = record["State"].ToString()
});
}
db.SaveChanges();
}
}
private void import_Click(object sender, EventArgs e)
{
OpenFileDialog ofd2 = new OpenFileDialog();
if (ofd2.ShowDialog() == DialogResult.OK)
{
string stringFileName = ofd2.FileName;
textBox1.Text = stringFileName;
SendExcelToDatabase(stringFileName);
}
}
}
}
static void GetDataTableFromCsv(string path, bool isFirstRowHeader)
{
string header = isFirstRowHeader ? "Yes" : "No";
string pathOnly = Path.GetDirectoryName(path);
string fileName = Path.GetFileName(path);
string sql = #"SELECT [ColumnNamesFromExcelSpreadSheet] FROM [" + fileName + "]";
using (OleDbConnection connection = new OleDbConnection(
#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathOnly +
";Extended Properties=\"Text;HDR=" + header + "\""))
using (OleDbCommand command = new OleDbCommand(sql, connection))
using (OleDbDataAdapter adapter = new OleDbDataAdapter(command))
{
DataTable dt = new DataTable();
dt = CultureInfo.CurrentCulture
adapter.Fill(dt);
StringBuilder sb = new StringBuilder();
foreach (DataRow dataRow in dt)
{
foreach (var item in dataRow.ItemArray)
{
sb.Append(item);
sb.Append(',');
}
}
}
}
This is a great little function for moving an excel spreadsheet into a datatable you can then insert the datatable into your sql db. Only thing you need to change is removing x amount of rows.
EDIT:
private void SendExcelToDatabase(string Filename)
{
int rowThread = HowManyRowsYouWouldLikeToSkipInExcel;
var data = ExcelFileRead(Filename);
using (var db = new ProviderBreakfastDBEntities())
{
foreach (DataRow record in data.Tables[0].Rows)
{
if (!(rowThreshold >= x))
{
int rank;
var isValidRank = int.TryParse(record["Ranking"].ToString(), out rank);
db.ProviderBreakfastExcels.Add(new ProviderBreakfastExcel
{
Ranking = isValidRank ? rank : new int?(),
Contact = record["Contact"].ToString(),
LastName = record["LastName"].ToString(),
FirstName = record["FirstName"].ToString(),
// Bedsize = isValidBedsize ? beds : new int?(),
Bedsize = Convert.ToInt32(record["Bedsize"].ToString()),
City = record["City"].ToString(),
Company = record["Company"].ToString(),
JobTitle = record["JobTitle"].ToString(),
State = record["State"].ToString()
});
}
}
db.SaveChanges();
x++
}
}
See if something like this works.

Object reference not set to an instance of an object c# - code posted

I kept trying to play with this code, but am getting,
Object reference not set to an instance of an object
one the marked arrow. Can anyone look at what I'm doing wrong? I've posted only the relevant code.
Thanks!
ERROR AT // MY ERROR HERE
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
namespace pkb
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
///
public partial class MainWindow : Window
{
string[] kbsubject = new string[4000];
string[] kbbody = new string[4000];
string[] wordsplit = new string[4000];
int[] hits = new int[4000];
StreamWriter WriteBody = new StreamWriter("kbsubjecttest.txt");
StreamReader readSubject = new StreamReader("kbsubject.txt");
StreamReader readBody = new StreamReader("kbbody.txt");
int IndexHolder = 0, counter = 0, counterSearch = 0, WordsIndex = 0, counterWord=0, ArrayIndex = 0;
string compareBody, compareSubject;
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
wordsplit = SearchBox.Text.Split(' ');
WordsIndex = 0;
counterWord = 0;
ArrayIndex = 0;
counterSearch = 0;
diagWindow.Items.Add(" counter = " + counter);
while (counter > counterSearch)
{ // MY ERROR BELOW
if (kbbody[counterWord].Contains(wordsplit[ArrayIndex])) // MY ERROR HERE
{
hits[ArrayIndex] = counterWord;
diagWindow.Items.Add(hits[ArrayIndex] + " " + kbbody[ArrayIndex]);
ArrayIndex++;
}
counterWord++;
WordsIndex++;
counterSearch++;
diagWindow.Items.Add(" we are on index " + counterSearch);
}
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
compareBody = readBody.ReadLine();
compareSubject = readSubject.ReadLine();
if (compareBody == compareSubject)
{
diagWindow.Items.Add(" Subject and Body Database compared successfully.");
IndexHolder = int.Parse(compareBody);
diagWindow.Items.Add(IndexHolder + " Index saved to variable.");
}
else
{
diagWindow.Items.Add("Error with comparison");
diagWindow.Items.Add("------------------------------");
diagWindow.Items.Add("Body comparison has " + compareBody + " where Subject comparison has " + compareSubject);
}
//load information into arrays
while (counter <= IndexHolder)
{
kbbody[counter] = readBody.ReadLine();
kbsubject[counter] = readSubject.ReadLine();
counter++;
}
diagWindow.Items.Add(counter + " Items successfully added into searchable database");
diagWindow.Items.Add(" counter = " + counter);
}
}
}
Suppose i enter "test" and no space on splitting it around ' ' there will be one element in wordsplit array and on second iterate there ll' be no other element So i guess you get error there.

Optimized Infragistics Excel

Recently we have encounter this issue about exporting reports to excel file using infragistics library.
Our report table contains more or less 1.26 million records as of now. We are trying to create an excel(2007) file for this, so approximately this will be 2 worksheets because only about 1million rows is supported by excel 2007 per sheet.
We have no problem during the creation of worksheets and during the filling of data into the worksheet, memory is manageable at this point.
Our problem is when writing the excel data into the stream(file, memory).
The memory consumption is just too high and when it reaches 1.8GB it will no longer continue.
P.S. This is a summary report, the client wants this in a single excel file.
Your recommendations are much appreciated!!!
Below is the code that i have pulled out from the actual source but i have replaced the data retrieval part and instead use a dummy data.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using System.Runtime;
using System.Diagnostics;
using Infragistics.Excel;
namespace ConsoleApplication1
{
class Program
{
static bool tip = true;
static void Main(string[] args)
{
var xls = Workbook.MaxExcelRowCount;
var xlsx =Workbook.MaxExcel2007RowCount;
var wb = new Workbook(WorkbookFormat.Excel2007, WorkbookPaletteMode.StandardPalette);
var ws = wb.Worksheets.Add("Sheet1");
var sheetCtr = 1;
var limit = 1256898;
var rr = 0;
for (var row = 0; row < limit; row++)
{
if (rr >= xlsx - 1)
{
//create new worksheet if row exceeded the limit
ws = wb.Worksheets.Add("Sheet" + sheetCtr.ToString());
rr = 0;
ClearMemory();
}
for (var col = 0; col < 10; col++)
{
ws.Rows[rr].Cells[col].Value = string.Format("data{0}-{1}", row, col);
}
Console.Write("Row=");
Console.Write(row.ToString());
Console.WriteLine();
rr++;
}
Console.Write("Saving worksheet...");
//this part uses too much memory
wb.Save("wb2.xlsx");
Console.WriteLine("Workbook saved.");
Console.WriteLine("Done");
Console.Read();
}
static void ClearMemory()
{
try
{
System.Diagnostics.Process proc = System.Diagnostics.Process.GetCurrentProcess();
if (tip == true)
{
proc.MaxWorkingSet = (IntPtr)((int)proc.MaxWorkingSet - 1);
proc.MinWorkingSet = (IntPtr)((int)proc.MinWorkingSet - 1);
}
else
{
proc.MaxWorkingSet = (IntPtr)((int)proc.MaxWorkingSet + 1);
proc.MinWorkingSet = (IntPtr)((int)proc.MinWorkingSet + 1);
}
tip = !tip;
}
catch (System.Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}

Search and retrieve xml in dataset?

I am trying to find some working examples to learn the wonders on Dataset with XML. Im using this example of the xml data. I want to search through all the CD nodes for the TITLE value.
DataSet dsXml = new DataSet();
dsXml.ReadXml(msXml);
look at using linq2xml. you could also use linq to "query" the dataset. http://msdn.microsoft.com/en-us/vbasic/bb688086.aspx
Here is a very simple C# code which will print all the "TITLE" in the provided XML:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DataSet dsXml = new DataSet();
dsXml.ReadXml("http://www.w3schools.com/xml/cd_catalog.xml");
for (int i = 0; i < dsXml.Tables.Count; i++)
{
Console.WriteLine("Table Name: " + dsXml.Tables[i].TableName);
int j = 1;
foreach (DataRow myRow in dsXml.Tables[i].Rows)
{
Console.Write("[" + j++ + "]");
foreach (DataColumn myColumn in dsXml.Tables[i].Columns)
{
if (myColumn.ColumnName.Equals("TITLE"))
Console.Write("[" + myRow[myColumn] + "]");
}
Console.WriteLine("");
}
}
}
}
}

Categories

Resources