read datatable rows and insert them into text file - text-files

I want to write to a text file all of the rows from a table (which contains only one column).
This is what I have:
try
{
DateTime DateTime = DateTime.Now;
using (StreamWriter sw = File.CreateText(AppVars.IntegrationFilesLocation + DateTime.ToString(DateFormat) + " Detail.txt"))
{
DataTable table = Database.GetDetailTXTFileData();
foreach (DataRow row in table.Rows)
{
sw.WriteLine(row[0].ToString());
}
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
The above is not writing to the text file. It jumps from table.Rows to outside the foreach block. Basically it's not reading the row. Does anyone know why?

This has been fixed. There was an issue with the query itself.

Related

skipping Rows in a CSV file to a certain word C#

I am new to C# coding and I have really tried to find an answer in any forum. I am using CSVHelper to read a CSV file and I want to skip a certain number of lines from the beginning of the file to a certain word. Now my code gives the following error message:
System.ObjectDisposedException: "Cannot read from a closed TextReader." Help me please :
private void cmdLoad_Click(object sender, EventArgs e)
{
OpenFileDialog OFDReader = new OpenFileDialog()
{ };
if (OFDReader.ShowDialog() == DialogResult.OK)
{
txtbox.Text = OFDReader.FileName;
}
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
Delimiter = ";", // Set delimiter
HasHeaderRecord = true,
//ShouldSkipRecord = (row) => row.Record[0].Contains("Date/Time"),
};
using (var reader = new StreamReader(OFDReader.FileName))
using (var csv = new CsvReader(reader, config))
{
//search for Line to start reader
string record = "Date/Time";
while (csv.Read())
{
if (csv.Read().Equals(record))
{
csv.Read();
csv.ReadHeader();
break;
}
using (var dr = new CsvDataReader(csv))
{
var dt = new DataTable();
dt.Load(dr);
dataGridView1.DataSource = dt; // Set datagridview source to datatable
}
}
}
}
}
}
I believe you just need to break out of the while (csv.Read()) when you find the "Date/Time" text. The CsvReader will do the rest from there.
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
Delimiter = ";", // Set delimiter
HasHeaderRecord = true
};
using (var reader = new StreamReader(OFDReader.FileName))
using (var csv = new CsvReader(reader, config))
{
//search for Line to start reader
string record = "Date/Time";
while (csv.Read())
{
if (csv.Context.Parser.RawRecord.Trim() == record)
{
break;
}
}
using (var dr = new CsvDataReader(csv))
{
var dt = new DataTable();
dt.Load(dr);
dt.Dump();
}
}

How to create excel file with multiple sheet name based on modules?

I work on c# desktop app I Can't export data to excel file with multiple tab(multi sheet).
only that i can do create excel file with only sheet based on data exist on data table module field.
I use open XML library
Data table data as below :
Divide Output Excel File To Multi Tab based On Module
PartId Company Files Tab Module
1222 micro Abc source 1
1321 silicon Abc source 1
1444 cd2 Abc types 2
1321 cd3 Abc types 2
1541 tvs Abc types 2
Expected Result :
Create File ABC.xlsx with two sheet first sheet name source and second sheet name types based on module and load data related to every sheet based on data exist on data table.
so if I have two modules meaning I have two sheet .
What I have tried:
public Boolean createExcelFile(DataTable Table,String FullFilePathName)
{
Boolean IsDone = false;
try
{
FileInfo CreatedFile = new FileInfo(FullFilePathName);
Boolean ISNew = false;
if (!CreatedFile.Exists)
{
ISNew = true;
}
using (var pck = new ExcelPackage(CreatedFile))
{
ExcelWorksheet ws;
if (ISNew == true)
{
ws = pck.Workbook.Worksheets.Add("Sheet");
ws.Cells[1, 1].LoadFromDataTable(Table, ISNew, OfficeOpenXml.Table.TableStyles.Light8);
}
else
{
ws = pck.Workbook.Worksheets.FirstOrDefault();
ws.Cells[2, 1].LoadFromDataTable(Table, ISNew);
}
pck.Save();
IsDone = true;
}
}
catch (Exception ex)
{
throw ex;
}
return IsDone;
}
but problem code above create one files with one sheet only
so How to create file with multi sheet based on module ?
I solved my issue by store multi data table on datasets then loop on it
DataSet ds = new DataSet();
var result = from rows in dt.AsEnumerable()
group rows by new { Module = rows["ModuleName"] } into grp
select grp;
foreach (var item in result)
{
ds.Tables.Add(item.CopyToDataTable());
}
Affected = new CExcel().createExcelFileForDs(ds, exportPath);
public Boolean createExcelFileForDs(DataSet ds, String FullFilePathName)
{
Boolean IsDone = false;
try
{
FileInfo CreatedFile = new FileInfo(FullFilePathName);
Boolean ISNew = false;
if (!CreatedFile.Exists)
{
ISNew = true;
}
using (var pck = new ExcelPackage(CreatedFile))
{
ExcelWorksheet ws;
foreach (DataTable Table in ds.Tables)
{
if (ISNew == true)
{
ws = pck.Workbook.Worksheets.Add(Convert.ToString(Table.Rows[0]["Tab name"]));
ws.Cells.Style.Font.Size = 11; //Default font size for whole sheet
ws.Cells.Style.Font.Name = "Calibri"; //Default Font name for whole sheet
if (System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.IsRightToLeft) // Right to Left for Arabic lang
{
ExcelWorksheetView wv = ws.View;
wv.ZoomScale = 100;
wv.RightToLeft = true;
ws.PrinterSettings.Orientation = eOrientation.Landscape;
ws.Cells.AutoFitColumns();
}
else
{
ExcelWorksheetView wv = ws.View;
wv.ZoomScale = 100;
wv.RightToLeft = false;
ws.PrinterSettings.Orientation = eOrientation.Landscape;
ws.Cells.AutoFitColumns();
}
ws.Cells.AutoFitColumns();
ws.Cells[1, 1].LoadFromDataTable(Table, ISNew, OfficeOpenXml.Table.TableStyles.Light8);
}
else
{
ws = pck.Workbook.Worksheets.FirstOrDefault();
ws.Cells[2, 1].LoadFromDataTable(Table, ISNew);
}
}
pck.Save();
IsDone = true;
}
}
catch (Exception ex)
{
throw ex;
}
return IsDone;
}

Displaying limited number of columns in grid using DataTable.ExtendedProperties

I want to display a limited number of columns in a grid that is connected to a DataTable as the data source. In an example that I found, it uses the property, ExtendedProperties to define how the column headers are displayed, the order and which columns are selected. However, when I use this, the columns, order and number displayed are the same as in the original DataTable.
Can anybody see what I am doing wrong?
This is a subset of the code. It is just the Customer's Table:
// initialize db connection variables
string conn = GetConnectionString();
// load some tables
string[] tables = "Customers, Orders, Order Details, Products, Employees, Shippers".Split(',');
foreach (string tableName in tables)
{
FillTable(_ds, tableName, conn);
}
dt = _ds.Tables["Customers"];
// re-arrange the columns on the customer table
//
dt.ExtendedProperties.Add("ShowColumns", new string[] {
"CustomerID, Customer",
"OrderCount, Orders",
"CompanyName, Company",
"ContactName, Contact",
"Phone",
"City",
"Region",
"Country",
});
// show customers to begin with
_flex.SetDataBinding(_ds, "Customers");
The method that sets up the columns:
// customize grid display to show selected columns, captions, formats, and data maps
void _flex_SetupColumns(object sender, System.EventArgs e)
{
// get grid that was just bound
C1FlexDataTree grid = sender as C1FlexDataTree;
if (grid == null || grid.DataSource == null)
return;
// get source DataTable
CurrencyManager cm = (CurrencyManager)BindingContext[grid.DataSource, grid.DataMember];
DataTable dt = ((DataView)cm.List).Table;
// apply custom column order, captions, format
string[] columns = dt.ExtendedProperties["ShowColumns"] as string[];
if (columns != null)
{
SetupColumns(grid, columns);
}
// apply custom data maps
foreach (Column gridColumn in grid.Cols)
{
DataColumn dataColumn = dt.Columns[gridColumn.Name];
if (dataColumn == null) continue;
gridColumn.DataMap = dataColumn.ExtendedProperties["DataMap"] as IDictionary;
if (gridColumn.DataMap != null)
{
gridColumn.TextAlign = TextAlignEnum.LeftCenter;
}
}
// all done, autosize to show mapped data
if (grid.AutoResize)
{
grid.AutoSizeCols(12);
}
}
The method, 'SetupColumns' is never called.
I figured this out. My problem was that I had not defined the Event within the grid so it was not firing. Once I did that, it worked fine.

Dynamic PIVOT using C# Linq

I am trying to use following code to create the PIVOT but its not working.
It's giving me compile time error. I don't know linq so unable to use it.
Please help :
DataTable Pivot(DataTable dt, DataColumn pivotColumn, DataColumn pivotValue) {
// find primary key columns
//(i.e. everything but pivot column and pivot value)
DataTable temp = dt.Copy();
temp.Columns.Remove( pivotColumn.ColumnName );
temp.Columns.Remove( pivotValue.ColumnName );
string[] pkColumnNames = temp.Columns.Cast(<DataColumn>)
.Select( c => c.ColumnName )
.ToArray();
// prep results table
DataTable result = temp.DefaultView.ToTable(true, pkColumnNames).Copy();
result.PrimaryKey = result.Columns.Cast(<DataColumn>).ToArray();
dt.AsEnumerable()
.Select(r =>; r[pivotColumn.ColumnName].ToString())
.Distinct().ToList()
.ForEach (c => result.Columns.Add(c, pivotColumn.DataType));
// load it
foreach( DataRow row in dt.Rows ) {
// find row to update
DataRow aggRow = result.Rows.Find(
pkColumnNames
.Select( c => row[c] )
.ToArray() );
// the aggregate used here is LATEST
// adjust the next line if you want (SUM, MAX, etc...)
aggRow[row[pivotColumn.ColumnName].ToString()] = row[pivotValue.ColumnName];
}
return result;
}
Code from : http://michaeljswart.com/2011/06/forget-about-pivot/
Moreover it tried to use following code, it works well except for it is not giving total sum for Value Column
public DataTable GetInversedDataTable(DataTable table, string columnX, string columnY, string columnZ, string nullValue, bool sumValues)
{
//Create a DataTable to Return
DataTable returnTable = new DataTable();
DataTable tempTable = table.Clone();
if (string.IsNullOrEmpty(columnX))
{
columnX = table.Columns[0].ColumnName;
}
tempTable.Columns.Remove(columnX);
//Add a Column at the beginning of the table
//returnTable.Columns.Add(columnY);
returnTable = tempTable.Clone();
//Read all DISTINCT values from columnX Column in the provided DataTale
List<string> columnXValues = new List<string>();
foreach (DataRow dr in table.Rows)
{
string columnXTemp = dr[columnX].ToString();
if (!columnXValues.Contains(columnXTemp))
{
//Read each row value, if it's different from others provided, add to the list of values and creates a new Column with its value.
columnXValues.Add(columnXTemp);
returnTable.Columns.Add(columnXTemp);
}
}
//Verify if Y and Z Axis columns re provided
if (!string.IsNullOrEmpty(columnY) && !string.IsNullOrEmpty(columnZ))
{
//Read DISTINCT Values for Y Axis Column
List<string> columnYValues = new List<string>();
foreach (DataRow dr in table.Rows)
{
if (!columnYValues.Contains(dr[columnY].ToString()))
{
columnYValues.Add(dr[columnY].ToString());
}
}
//Loop all Column Y Distinct Value
foreach (string columnYValue in columnYValues)
{
//Creates a new Row
DataRow drReturn = returnTable.NewRow();
drReturn[0] = columnYValue;
//foreach column Y value, The rows are selected distincted
DataRow[] rows = table.Select((columnY + "='") + columnYValue + "'");
//Read each row to fill the DataTable
foreach (DataRow dr in rows)
{
string rowColumnTitle = dr[columnX].ToString();
//Read each column to fill the DataTable
foreach (DataColumn dc in returnTable.Columns)
{
if (dc.ColumnName == rowColumnTitle)
{
//If Sum of Values is True it try to perform a Sum
//If sum is not possible due to value types, the value displayed is the last one read
if (sumValues)
{
try
{
drReturn[rowColumnTitle] = Convert.ToDecimal(drReturn[rowColumnTitle]) + Convert.ToDecimal(dr[columnZ]);
}
catch
{
drReturn[rowColumnTitle] = dr[columnZ];
}
}
else
{
drReturn[rowColumnTitle] = dr[columnZ];
}
}
}
}
returnTable.Rows.Add(drReturn);
}
}
else
{
throw new Exception("The columns to perform inversion are not provided");
}
//if a nullValue is provided, fill the datable with it
if (!string.IsNullOrEmpty(nullValue))
{
foreach (DataRow dr in returnTable.Rows)
{
foreach (DataColumn dc in returnTable.Columns)
{
if (string.IsNullOrEmpty(dr[dc.ColumnName].ToString()))
{
dr[dc.ColumnName] = nullValue;
}
}
}
}
return returnTable;
}
GetInversedDataTable(dtNormal, "Dated", "OrderStatus", "Qty", " ", true);
Please help :)
Here is the code with the compilation errors corrected:
DataTable Pivot(DataTable dt, DataColumn pivotColumn, DataColumn pivotValue) {
// find primary key columns
//(i.e. everything but pivot column and pivot value)
DataTable temp = dt.Copy();
temp.Columns.Remove( pivotColumn.ColumnName );
temp.Columns.Remove( pivotValue.ColumnName );
string[] pkColumnNames = temp.Columns.Cast<DataColumn>()
.Select( c => c.ColumnName )
.ToArray();
// prep results table
DataTable result = temp.DefaultView.ToTable(true, pkColumnNames).Copy();
result.PrimaryKey = result.Columns.Cast<DataColumn>().ToArray();
dt.AsEnumerable()
.Select(r => r[pivotColumn.ColumnName].ToString())
.Distinct().ToList()
.ForEach (c => result.Columns.Add(c, pivotColumn.DataType));
// load it
foreach( DataRow row in dt.Rows ) {
// find row to update
DataRow aggRow = result.Rows.Find(
pkColumnNames
.Select( c => row[c] )
.ToArray() );
// the aggregate used here is LATEST
// adjust the next line if you want (SUM, MAX, etc...)
aggRow[row[pivotColumn.ColumnName].ToString()] = row[pivotValue.ColumnName];
}
return result;
}
I changed Cast(<DataColumn>) to Cast<DataColumn>() in two locations and got rid of the semicolon in the middle of a lambda expression. The second part of your question is a little trickier. You may want to ask it as its own question.
Good one., but you might want to replace the below line
.ForEach (c => result.Columns.Add(c, pivotColumn.DataType));
with this (change pivotColumn to pivotValue)
.ForEach (c => result.Columns.Add(c, pivotValue.DataType));
Works perfectly for my requirement.

How to extract bullet information from word document?

I want to extract information of bullets present in word document.
I want something like this :
Suppose the text below, is in word document :
Steps to Start car :
Open door
Sit inside
Close the door
Insert key
etc.
Then I want my text file like below :
Steps to Start car :
<BULET> Open door </BULET>
<BULET> Sit inside </BULET>
<BULET> Close the door </BULET>
<BULET> Insert key </BULET>
<BULET> etc.</BULET>
I am using C# language to do this.
I can extract paragraphs from word document and directly write them in text file with some formatting information like whether text is bold or is in italics, etc. but dont know how to extract this bullet information.
Can anyone please tell me how to do this?
Thanks in advance
You can do it by reading each sentence. doc.Sentences is an array of Range object. So you can get same Range object from Paragraph.
foreach (Paragraph para in oDoc.Paragraphs)
{
string paraNumber = para.Range.ListFormat.ListLevelNumber.ToString();
string bulletStr = para.Range.ListFormat.ListString;
MessageBox.Show(paraNumber + "\t" + bulletStr + "\t" + para.Range.Text);
}
Into paraNumber you can get paragraph level and into buttetStr you can get bullet as string.
I am using this OpenXMLPower tool by Eric White. Its free and available at NUGet package. you can install it from Visual studio package manager.
He has provided a ready to use code snippet. This tool has saved me many hours. Below is the way I have customized code snippet to use for my requirement.
Infact you can use these methods as it in your project.
private static WordprocessingDocument _wordDocument;
private StringBuilder textItemSB = new StringBuilder();
private List<string> textItemList = new List<string>();
/// Open word document using office SDK and reads all contents from body of document
/// </summary>
/// <param name="filepath">path of file to be processed</param>
/// <returns>List of paragraphs with their text contents</returns>
private void GetDocumentBodyContents()
{
string modifiedString = string.Empty;
List<string> allList = new List<string>();
List<string> allListText = new List<string>();
try
{
_wordDocument = WordprocessingDocument.Open(wordFileStream, false);
//RevisionAccepter.AcceptRevisions(_wordDocument);
XElement root = _wordDocument.MainDocumentPart.GetXDocument().Root;
XElement body = root.LogicalChildrenContent().First();
OutputBlockLevelContent(_wordDocument, body);
}
catch (Exception ex)
{
logger.Error("ERROR in GetDocumentBodyContents:" + ex.Message.ToString());
}
}
// This is recursive method. At each iteration it tries to fetch listitem and Text item. Once you have these items in hand
// You can manipulate and create your own collection.
private void OutputBlockLevelContent(WordprocessingDocument wordDoc, XElement blockLevelContentContainer)
{
try
{
string listItem = string.Empty, itemText = string.Empty, numberText = string.Empty;
foreach (XElement blockLevelContentElement in
blockLevelContentContainer.LogicalChildrenContent())
{
if (blockLevelContentElement.Name == W.p)
{
listItem = ListItemRetriever.RetrieveListItem(wordDoc, blockLevelContentElement);
itemText = blockLevelContentElement
.LogicalChildrenContent(W.r)
.LogicalChildrenContent(W.t)
.Select(t => (string)t)
.StringConcatenate();
if (itemText.Trim().Length > 0)
{
if (null == listItem)
{
// Add html break tag
textItemSB.Append( itemText + "<br/>");
}
else
{
//if listItem == "" bullet character, replace it with equivalent html encoded character
textItemSB.Append(" " + (listItem == "" ? "•" : listItem) + " " + itemText + "<br/>");
}
}
else if (null != listItem)
{
//If bullet character is found, replace it with equivalent html encoded character
textItemSB.Append(listItem == "" ? " •" : listItem);
}
else
textItemSB.Append("<blank>");
continue;
}
// If element is not a paragraph, it must be a table.
foreach (var row in blockLevelContentElement.LogicalChildrenContent())
{
foreach (var cell in row.LogicalChildrenContent())
{
// Cells are a block-level content container, so can call this method recursively.
OutputBlockLevelContent(wordDoc, cell);
}
}
}
if (textItemSB.Length > 0)
{
textItemList.Add(textItemSB.ToString());
textItemSB.Clear();
}
}
catch (Exception ex)
{
.....
}
}
I got the answer.....
First I was converting doc on paragraph basis. But instead of that if we process doc file sentence by sentence basis, it is possible to determine whether that sentence contains bullet or any kind of shape or if that sentence is part of table. So once we get this information, then we can convert that sentence appropriately. If someone needs source code, I can share it.

Resources