Read in xls file as well as current csv file in app - c#

I have the following code -
private void button1_Click(object sender, EventArgs e)
{
string csv = File.ReadAllText("FilePath");
WebService.function res = new WebService.function();
XDocument doc = ConvertCsvToXML(csv, new[] { "," });
I was wondering how a could adjust the code so that it not only reads .csv files but also .xls files?
I created a public XDocument to do this -
public XDocument ConvertCsvToXML(string csvString, string[] separatorField)
{
var sep = new[] { "\n" };
string[] rows = csvString.Split(sep, StringSplitOptions.RemoveEmptyEntries);
var xsurvey = new XDocument(
new XDeclaration("1.0", "UTF-8", "yes"));
var xroot = new XElement("details");

If I understand your question correctly, you are looking to parse an excel file as text in the same manner that you parse the csv file. While this is possible, you should consider using Office Interop interfaces to do this. If you want to parse the raw file you'll need to account for the different formats between Office versions and a whole slew of encoding/serialization tasks; no small task.
Here are some resources to get you started:
Reading Excel from C#
How to Automate Excel from C#

I'm not sure from your question...but if you are asking how to read an excel file in c#, this will work:
string fileName = [insert path and name];
string connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;data source={0}; Extended Properties=Excel 8.0;", fileName); // Create the data adapter pointing to the spreadsheet
var oa = new OleDbDataAdapter("SELECT * FROM [xxx$]", connectionString); // xxx is tab name
// Create a blank data set
var ds = new DataSet(); // Fill the data set using the adapter
oa.Fill(ds, "table1"); // Create a data table from the data set
DataTable dt1 = ds.Tables["table1"];
foreach (DataRow dr in dt1.Rows)
{
...
}

Related

StreamWriter along with XmlSerializer in DotNet6 does not write WhiteSpaces?

Actually I tried this basic code in C# which serializes the DataSet into XML document.
static void Main(string[] args)
{
XmlSerializer ser = new XmlSerializer(typeof(DataSet));
// Creates a DataSet; adds a table, column, and ten rows.
DataSet ds = new DataSet("myDataSet");
DataTable t = new DataTable("table1");
DataColumn c = new DataColumn("thing");
t.Columns.Add(c);
ds.Tables.Add(t);
DataRow r;
for (int i = 0; i < 10; i++)
{
r = t.NewRow();
r[0] = "Thing " + i;
t.Rows.Add(r);
}
StreamWriter writer = new StreamWriter("DemoNet5.xml");
ser.Serialize(writer, ds);
writer.Close();
}
And this creates the "DemoNet5.xml" file with proper WhiteSpaces and Indentation in .NET 5. But When I try to run the same code in .NET 6
I am not getting the WhiteSapces and Indentation so that the contents of the xml are written in single line.
Later on when I try to read that .xml document I face issues.
Is there someone who can help me with this ? I want my xml contents to be in proper format that is with proper indetation and WhiteSpaces.
Xml file created using .NET6
I have also attached the XML document created using DotNet6.

Is there a way for extracting an Excel file from an ado.net query and adding custom columns to it using c#

I have an Excel file template, and I need to extract the data from a SQL Server database to this Excel file using C# as same as the template file.
The problem is that I need to add another column using C# to the Excel file, to make this extracted file look like the template file.
So I will not extract the Excel file's data from my web-form application directly.
I need to add some additional columns first.
Convert SQL to CSV while writing SQL result add your custom column data as well. CSV will open in excel by default.
private void SQLToCSV(string query, string Filename)
{
SqlConnection conn = new SqlConnection(connection);
conn.Open();
SqlCommand cmd = new SqlCommand(query, conn);
SqlDataReader result = cmd.ExecuteReader();
using (System.IO.StreamWriter fs = new System.IO.StreamWriter(Filename))
{
// Loop through the fields and add headers
for (int i = 0; i < result.FieldCount; i++)
{
string colval = result.GetColumnName(i);
if (colval.Contains(","))
colval = "\"" + colval + "\"";
fs.Write(colval + ",");
}
//CONCATENATE THE COLUMNS YOU WANT TO ADD IN RESULT HERE
fs.WriteLine();
// Loop through the rows and output the data
while (result.Read())
{
for (int i = 0; i < result.FieldCount; i++)
{
string value = result[i].ToString();
if (value.Contains(","))
value = "\"" + value + "\"";
fs.Write(value + ",");
}
fs.WriteLine();
}
fs.Close();
}
}
You can covert csv to excel
using Excel = Microsoft.Office.Interop.Excel;
private void Convert_CSV_To_Excel()
{
// Rename .csv To .xls
System.IO.File.Move(#"d:\Test.csv", #"d:\Test.csv.xls");
var _app = new Excel.Application();
var _workbooks = _app.Workbooks;
_workbooks.OpenText("Test.csv.xls",
DataType: Excel.XlTextParsingType.xlDelimited,
TextQualifier: Excel.XlTextQualifier.xlTextQualifierNone,
ConsecutiveDelimiter: true,
Semicolon: true);
// Convert To Excle 97 / 2003
_workbooks[1].SaveAs("NewTest.xls", Excel.XlFileFormat.xlExcel5);
_workbooks.Close();
}

From EXCEL to XSD generated class in C#

I have this situation, I have been provided with an XSD schema consisting of four XSD files which I was able to convert to a class using the XSD.exe tool and include it in my project, for this example this class is named "Test_XSD". On the other side I have a populated excel sheet table consisting of 10 columns which I need to map to certain elements in the "Text XSD". The "Test_XSD" schema is complex however if I map the 10 columns to their relevant elements is sufficient since many other elements are not mandatory. I have searched and searched but cannot find a simple example to start building on it.
I am able to read the excel file in Visual Studio and convert to XML, however this does not conform with the XSD generated class. I know that I have to create an instance of the "Test_XSD" and load it with the data from the Excel but I don't have any clue from where to start. Can someone explain what needs to be done.
This is what I've done so far, not too much I admit but this is something totally new for me and to be honest I didn't have yet understood the way forward although I've researched a lot.
static void Main(string[] args)
{
// Using an OleDbConnection to connect to excel
var cs = $#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={#"C:\AAAA\Report.xlsx"};Extended Properties=""Excel 12.0 Xml; HDR = Yes; IMEX = 2"";Persist Security Info=False";
var con = new OleDbConnection(cs);
con.Open();
// Using OleDbCommand to read data of the sheet(sheetName)
var cmd = new OleDbCommand($"select * from [Sheet1$]", con);
var ds = new DataSet();
var da = new OleDbDataAdapter(cmd);
da.Fill(ds);
//// Convert DataSet to Xml
//using (var fs = new FileStream(#"C:\Users\MT2362\Downloads\CRS_XML.xml", FileMode.CreateNew))
//{
// using (var xw = new XmlTextWriter(fs, Encoding.UTF8))
// {
// ds.WriteXml(xw);
// }
//}
XSD xsd = new XSD();
xsd.version = "TEST VERSION";
Console.WriteLine(xsd.version);
Console.ReadKey();
}
I've noted taht the class generated from the XSD ("Test_XSD") is composed of multiple partial class, hence I think that an instance for each class must be created.
Thanks in advance, code snippets are highly appreciated.
The object of your XSD class would have public properties. If you set the value of these properties (similar to your .version in your example), then your object is fully populated.
Is this what you want ?
After running the XSD.exe tool, the output would be a list of C# classes that would be available to you.
Since you were able to successfully read from the Excel file and create and XML file for the dataset.
Perform the following:
Add a new class to your project as follows:
public class ExcelNameSpaceXmlTextReader : XmlTextReader
{
public ExcelNameSpaceXmlTextReader(System.IO.TextReader reader)
: base(reader) { }
public override string NamespaceURI
{
get { return ""; }
}
}
Then in a separate Utitlity class add a deserializer function as follows
public class Utility
{
public T FromXml<T>(String xml)
{
T returnedXmlClass = default(T);
using (TextReader reader = new StringReader(xml))
{
returnedXmlClass = (T)new XmlSerializer(typeof(T)).Deserialize(new ExcelNameSpaceXmlTextReader(reader));
}
return returnedXmlClass;
}
}
Now add code to consume the read in data from XML as the object you want to serialize the data to by consuming the generic Utility function
So your code would be like
static void Main(string[] args)
{
// Using an OleDbConnection to connect to excel
var cs = $#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={#"C:\AAAA\Report.xlsx"};Extended Properties=""Excel 12.0 Xml; HDR = Yes; IMEX = 2"";Persist Security Info=False";
var con = new OleDbConnection(cs);
con.Open();
// Using OleDbCommand to read data of the sheet(sheetName)
var cmd = new OleDbCommand($"select * from [Sheet1$]", con);
var ds = new DataSet();
var da = new OleDbDataAdapter(cmd);
da.Fill(ds);
// Convert DataSet to Xml
using (var fs = new FileStream(#"C:\Users\MT2362\Downloads\CRS_XML.xml", FileMode.CreateNew))
{
using (var xw = new XmlTextWriter(fs, Encoding.UTF8))
{
ds.WriteXml(xw);
}
}
XDocument doc = XDocument.Load("C:\Users\MT2362\Downloads\CRS_XML.xml");
Test_XSD test_XSD = Utility.FromXml<Test_XSD>(doc.Document.ToString());
XSD xsd = new XSD();
xsd.version = "TEST VERSION";
Console.WriteLine(xsd.version);
Console.ReadKey();
}

Reading XML with Schema XSD

I have a problem with the reading an xml, that was created saving the same schema that i used to read.
When I read a DataTable, for example Person, that has one row, the DataTable read the row but show me like all columns where null, when all columns are not null.
The code I use is the following
private DataSet LoadShema(string path)
{
string _archivoXsd = System.AppDomain.CurrentDomain.BaseDirectory +"Scheme.xsd";//HERE IS WHERE THE .XSD FILE IS
DataSet esquemaXSD = new DataSet();
string archivoXml = path;
FileStream FsXSD = new FileStream(_archivoXsd, FileMode.Open);
FileStream FsXML = new FileStream(archivoXml, FileMode.Open);
XmlTextReader xtrXSD = new XmlTextReader(FsXSD);
try
{
esquemaXSD.ReadXmlSchema(xtrXSD);
xtrXSD.Close();
FsXSD.Close();
XmlTextReader xtrXML = new XmlTextReader(FsXML);
esquemaXSD.ReadXml(xtrXML);
xtrXML.Close();
FsXML.Close();
}
catch
{
}
return esquemaXSD;
}
This is how I load the xml in the scheme, then another thing I do is assigning:
_dtPerson = new DataTable();
_dtPerson = esquemaXSD.Tables["Person"];
and for last, what I do is the following:
if (_dtPerson.Rows.Count == 1)
{
string name = Convert.ToString(_dtPerson.Rows[0]["Name"]);
}
and when i do the last code line, an exception that said "Can not convert DBNull object to other types".

C# VS2005 Convert Pipe Delimited .TXT to Excel Workbook .XLS

I am using VS2005 C# and im trying to convert a pipe delimited text file to excel workbook format. Below is my code:
public partial class TextToExcel : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void SaveAsExcelBtn_Click(object sender, EventArgs e)
{
string xlExtension = ".csv";
string strExcelOutputFilename = "C:/Documents and Settings/rhlim/My Documents/" + DateTime.Now.ToString("yyyyMMddHHmmss") + xlExtension;
// Before attempting to import the file, verify
// that the FileUpload control contains a file.
if (TextFile.HasFile)
{
// Get the name of the Excel spreadsheet.
string strFileName = Server.HtmlEncode(TextFile.FileName);
// Get the extension of the text.
string strExtension = Path.GetExtension(strFileName);
// Validate the file extension.
if (strExtension != ".TXT" && strExtension!=".txt")
{
Response.Write("<script>alert('Failed to import. Cause: Invalid text file.');</script>");
return;
}
// Generate the file name to save the text file.
//string strUploadFileName = "C:/Documents and Settings/rhlim/My Documents/Visual Studio 2005/WebSites/SoD/UploadFiles/" + DateTime.Now.ToString("yyyyMMddHHmmss") + strExtension;
using (StreamWriter outputWriter = new StreamWriter(File.Create(strExcelOutputFilename)))
{
StreamReader inputReader = new StreamReader(TextFile.FileContent);
string fileContent = inputReader.ReadToEnd();
fileContent = fileContent.Replace('|', ';');
outputWriter.Write(fileContent);
TextFile.SaveAs(strExcelOutputFilename);
inputReader.Close();
}
//string strExcelOutputFilename = "C:/Documents and Settings/rhlim/My Documents/" + DateTime.Now.ToString("yyyyMMddHHmmss")+xlExtension;
// Save the Excel spreadsheet on server.
//TextFile.SaveAs (strExcelOutputFilename);
}
else Response.Write("<script>alert('Failed to import. Cause: No file found');</script>");
}
}
Currently I am having some file saving errors
Any suggestions? Thanks a lot!
That's because Excel doesnt support pipelines you have to convert it so comma's or semicolumns like:
using (StreamWriter outputWriter = new StreamWriter(File.Create(strExcelOutputFilename)))
{
StreamReader inputReader = new StreamReader(TextFile.FileContent);
string fileContent = inputReader.ReadToEnd();
fileContent = fileContent.Replace('|', ',');
outputWriter.Write(fileContent);
}
I googled and hope it will help you: http://csharp.net-informations.com/excel/csharp-create-excel.htm
Or, already answered: Create Excel (.XLS and .XLSX) file from C#
At the first link, the line xlWorkSheet.Cell[x,y] to put element in the dedicated cell.
FYI, xlsx format(new from Office 2007) will give you a great manipulation capability with code.
For generating and manipulating excel files, I personally prefer the NPOI library. Download it from Codeplex, add reference to the NPOI dlls to your project. Store a “template” excel file you would like in a known location, with the any column headers/formatting that you need. Then you just use npoi to make a copy of the template file and manipulate it at a sheet/row/column level and put whatever data you want.
The sample code snippet looks something like this. Assuming you have split your input into a List of strings
const string ExcelTemplateFile = "~/Resources/ExcelInputTemplate.xls";
const string ExcelWorksheetName = "Output Worksheet";
const int RequiredColumn = 1;
private HSSFWorkbook CreateExcelWorkbook(IEnumerable<String> inputData)
{
FileStream fs = new FileStream(Server.MapPath(ExcelTemplateFile), FileMode.Open, FileAccess.Read);
// Getting the complete workbook...
HSSFWorkbook templateWorkbook = new HSSFWorkbook(fs, true);
// Getting the worksheet by its name...
HSSFSheet sheet = templateWorkbook.GetSheet(ExcelWorksheetName);
int startRowIterator = 1;
foreach (string currentData in inputData)
{
sheet.CreateRow(startRowIterator).CreateCell(RequiredColumn).SetCellValue(currentData);
}
}

Categories