OpenXML Excel File Parsing - asp.net

I have an excel document that is supposed to be parsed using the following block of code:
var handler = new ExcelHandler(byteStream);
var currentExcelDocument = handler.CurrentDocument;
//now if the document is null
if (currentExcelDocument == null)
{
throw new Exception("Excel file handle missing");
}
var wokrbookpart = currentExcelDocument.WorkbookPart;
//get a list of all the sheets
string text = String.Empty;
var sheets = wokrbookpart.Workbook.Descendants<Sheet>().ToList();
foreach (var sh in sheets)
{
//now we have the sheets but the data must be in the first sheet
var themainsheet = sh;
if (themainsheet == null)
throw new ArgumentException("sheetName");
//now we need a reference to the worksheetpart
var worksheetpart = (WorksheetPart)wokrbookpart.GetPartById(themainsheet.Id);
SheetData data = worksheetpart.Worksheet.Elements<SheetData>().First();
//now we have a reference to the cells that contain data we start passing the data
foreach (Row r in data.Elements<Row>())
{
//we get the cells in the row
var cells = r.Elements<Cell>().ToList();
foreach (var i in cells)
{
text += i.CellValue.InnerText;
}
}
}
return text;
the excel file is uploaded via a fileupload control in asp.net and the stream is passed into the above block of code.
All is well though but then when i display the resulting text in the label, I see that the
result of reading the cell values is displayed as a sequence of numbers even though i am hindred percent sure that there are no numbers in the data
Please what could i be doing wrong??

Related

Make the Title row in grey background with Blue fonts after convert json to excel

I have developed a json to csv file download function everything works fine but I'm not sure how to make the first row of the table which are "Vehicle, Date, Location, Speed" background color in lightgrey and font in blue and always expand the columns upon opening the file
Here is the fiddle http://jsfiddle.net/harvindr/v5cw94u8/1/
function JSONToCSVConvertor(JSONData, ReportTitle, ShowLabel) {
//If JSONData is not an object then JSON.parse will parse the JSON string in an Object
var arrData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData;
var CSV = '';
//Set Report title in first row or line
CSV += ReportTitle + '\r\n\n';
//This condition will generate the Label/Header
if (ShowLabel) {
var row = "";
//This loop will extract the label from 1st index of on array
for (var index in arrData[0]) {
//Now convert each value to string and comma-seprated
row += index + ',';
}
row = row.slice(0, -1);
//append Label row with line break
CSV += row + '\r\n';
}
//1st loop is to extract each row
for (var i = 0; i < arrData.length; i++) {
var row = "";
//2nd loop will extract each column and convert it in string comma-seprated
for (var index in arrData[i]) {
row += '"' + arrData[i][index] + '",';
}
row.slice(0, row.length - 1);
//add a line break after each row
CSV += row + '\r\n';
}
if (CSV == '') {
alert("Invalid data");
return;
}
//Generate a file name
// var fileName = "MyReport_";
//this will remove the blank-spaces from the title and replace it with an underscore
// fileName += ReportTitle.replace(/ /g,"_");
//Initialize file format you want csv or xls
var uri = 'data:text/csv;charset=utf-8,' + escape(CSV);
// Now the little tricky part.
// you can use either>> window.open(uri);
// but this will not work in some browsers
// or you will not get the correct file extension
//this trick will generate a temp <a /> tag
var link = document.createElement("a");
link.href = uri;
//set the visibility hidden so it will not effect on your web-layout
link.style = "visibility:hidden";
link.download = "PrognosData.csv";
//this part will append the anchor tag and remove it after automatic click
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}

Any way to find out the fields in a datasource?

I'd like to write a script to dump the contents of a given table to a spreadsheet regardless of the fields, (I've done this for several individual tables but want to write something universal).
Will
app.models.filesToCopy.fields._values;
be involved?
I would say the most generic way would be to establish a server function and pass in the model name as a parameter. Then establish a script similar to what I put below. You can even format your data based on the field type if wanted by using fields[n].type in a if or select statement.
function YourFunction(YourModel) {
var sheetfile = SpreadsheetApp.create('test file');
var ss = sheetfile.getActiveSheet();
var fields = app.metadata.models[YourModel].fields;
var results = app.models[YourModel].newQuery().run();
var i, j;
var sheetdata = [], header = [];
for (j in fields) {
header.push(fields[j].displayName);
}
sheetdata.push(header);
for (var i in results) {
var data = [];
for (j in fields) {
data.push(results[i][fields[j].name]);
}
sheetdata.push(data);
}
ss.getRange(1,1,sheetdata.length,fields.length).setValues(sheetdata);
}

asp.net open xml to download .xlsx file

I'm trying to supply a .xlsx file from a grid, I think most of the hard work is done. I'm picking up a template file and filling it with data.
I' getting an error 'file not found' on Response.WriteFile.
by the looks of the example (linked below) this should just be the intended file name, but I imagine this needs to be a path to the file?, so do I need to save my 'myDoc' object to the server and then provide the path in the Reponse.WriteFile.
It doesn't seem like that is what is meant by the example.
the code i'm using is a modified version of : http://technet.weblineindia.com/web/export-data-to-excel-using-openxml-sdk/
due to using sharepoint to store the template file I just had to create a filestream rather than supply the URL to the file.
here is my code:
// Create cell reference array
string[] CellReferenceArray = new string[] { "A", "B", "C", "D", "E" };
//Open your saved excel file that you have created using template file.
using (SpreadsheetDocument myDoc = SpreadsheetDocument.Open(file.OpenBinaryStream(), true))
{
// Create reference of main Workbook part, which contains all reference.
WorkbookPart objworkbook = myDoc.WorkbookPart;
// Create style sheet object that will be used for applying styling.
Stylesheet objstyleSheet = objworkbook.WorkbookStylesPart.Stylesheet;
// pick up first worksheet
WorksheetPart objworksheet = objworkbook.WorksheetParts.First();
// will be used in end while creating sheet data
string objorigninalSheetId = objworkbook.GetIdOfPart(objworksheet);
WorksheetPart objreplacementPart = objworkbook.AddNewPart<WorksheetPart>();
string objreplacementPartId = objworkbook.GetIdOfPart(objreplacementPart);
// Create object reader to read from excel file.
OpenXmlReader objreader = OpenXmlReader.Create(objworksheet);
// create writer object to write in excel sheet.
OpenXmlWriter objOpenXmwriter = OpenXmlWriter.Create(objreplacementPart);
int i = 1;
Row r = new Row();
Cell c = new Cell();
Columns col1 = new Columns();
UInt32 index = 0;
while (objreader.Read())
{
if (objreader.ElementType == typeof(SheetData))
{
if (objreader.IsEndElement)
continue;
objOpenXmwriter.WriteStartElement(new SheetData());
objOpenXmwriter.WriteStartElement(r);
// Loop to insert header
foreach (DataColumn colHead in YoutdTName.Columns)
{
c = new Cell
{
DataType = CellValues.String,
CellReference = CellReferenceArray[i] + Convert.ToString(index)
};
CellValue v1 = new CellValue(colHead.ColumnName.ToString());
c.Append(v1);
objOpenXmwriter.WriteElement(c);
i += 1;
}
objOpenXmwriter.WriteEndElement();
index += 1;
//Loop to insert datatable row in excel
foreach (DataRow dr in YoutdTName.Rows)
{
objOpenXmwriter.WriteStartElement(r);
i = 1;
foreach (DataColumn col in YoutdTName.Columns)
{
c = new Cell
{
DataType = CellValues.String,
CellReference = CellReferenceArray[i] + Convert.ToString(index)
};
CellValue v1 = new CellValue(dr[col].ToString());
c.AppendChild(v1);
objOpenXmwriter.WriteElement(c);
i += 1;
}
objOpenXmwriter.WriteEndElement();
index += 1;
}
objOpenXmwriter.WriteEndElement();
}
}
//close all objects
objreader.Close();
objOpenXmwriter.Close();
Sheet sheet = objworkbook.Workbook.Descendants<Sheet>().Where(s => s.Id.Value.Equals(objorigninalSheetId)).First();
sheet.Id.Value = objreplacementPartId;
objworkbook.DeletePart(objworksheet);
}
Response.AddHeader("Content-Disposition", "inline;filename=YourExcelfileName.xlxs");
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.WriteFile("YourExcelfileName.xlxs");
Response.Flush();
Response.End();
}
Use HttpResponse.BinaryWrite instead and take the underlying stream from your SpreadsheetDocument-instance .
http://msdn.microsoft.com/en-us/library/system.web.httpresponse.binarywrite(v=vs.110).aspx

Unable to check existing XML nodes in Adobe Flex 3

I am getting an XML data from server (please refer to xmlData value).
I need to:
Create another XML with non-duplicates Folders
Create another XML with final count on monthly basis.
I am unable to do this with below code and getting duplicate records.
private var xmlData:XML = new XML("<root><SUMMARY_RECORD><FOLDER>Folder1</FOLDER><COUNT>100</COUNT><MONTH>Feb</MONTH><QUARTER>Q1</QUARTER><YEAR>2014</YEAR></SUMMARY_RECORD><SUMMARY_RECORD><FOLDER>Folder1</FOLDER><COUNT>100</COUNT><MONTH>Feb</MONTH><QUARTER>Q1</QUARTER><YEAR>2014</YEAR></SUMMARY_RECORD></root>");
var folderDataXML:XML = new XML("<root></root>");
var folderDGDataXML:XML = new XML("<root></root>");
private function loaded():void{
var item:XML;
folderDGDataXML.appendChild(new XML("<FOLDER_NAME><Name>ALL</Name></FOLDER_NAME>"));
for each (item in xmlData.SUMMARY_RECORD){
if (folderDGDataXML.FOLDER_NAME.(Name==item.FOLDER).toString() == ""){
folderDGDataXML.appendChild(new XML("<FOLDER_NAME><Name>"+item.FOLDER+"</Name></FOLDER_NAME>"));
}
if (folderDataXML.SUMMARY_RECORD.(Name==item.MONTH).toXMLString() == ""){
folderDataXML.appendChild(new XML("<SUMMARY_RECORD><Name>"+item.MONTH+"</Name><COUNT>"+item.COUNT+"</COUNT></SUMMARY_RECORD>"));
}else{
var count:int = Number(folderDataXML.SUMMARY_RECORD.(Name==item.MONTH).COUNT) + Number(item.COUNT);
folderDataXML.SUMMARY_RECORD.(Name==item.MONTH).COUNT = count;
}
}
}
Final output, folderDGDataXML:
<root>
<FOLDER_NAME>
<Name>ALL</Name>
</FOLDER_NAME>
<FOLDER_NAME>
<Name>Folder1</Name>
</FOLDER_NAME>
<FOLDER_NAME>
<Name>Folder1</Name>
</FOLDER_NAME>
</root>
folderDataXML:
<root>
<SUMMARY_RECORD>
<Name>Feb</Name>
<COUNT>100</COUNT>
</SUMMARY_RECORD>
<SUMMARY_RECORD>
<Name>Feb</Name>
<COUNT>100</COUNT>
</SUMMARY_RECORD>
</root>
What am I doing wrong?
After getting correct XML, I need to populate datagrid & column chart.
Try this one
In XML Checking the elements present or not with hasOwnProperty or we can use in operator anyhow our case if it is based on value try like this way folderDGDataXML.descendants("FOLDER_NAME").(Name.text() == "Folder1"); //Return always XMLList. With the help of length() we can predict element with value occur or not.
Hope this will work for you.
var xmlData:XML = new XML("<root><SUMMARY_RECORD><FOLDER>Folder1</FOLDER><COUNT>100</COUNT><MONTH>Feb</MONTH><QUARTER>Q1</QUARTER><YEAR>2014</YEAR></SUMMARY_RECORD><SUMMARY_RECORD><FOLDER>Folder1</FOLDER><COUNT>100</COUNT><MONTH>Feb</MONTH><QUARTER>Q1</QUARTER><YEAR>2014</YEAR></SUMMARY_RECORD></root>");
var folderDataXML:XML = new XML("<root></root>");
var folderDGDataXML:XML = new XML("<root></root>");
var item:XML;
folderDGDataXML.appendChild(new XML("<FOLDER_NAME><Name>ALL</Name></FOLDER_NAME>"));
for each (item in xmlData.SUMMARY_RECORD)
{
var folderName:String = item.FOLDER.text();
var monthName:String = item.MONTH.text();
var existXMLList:XMLList = folderDGDataXML.descendants("FOLDER_NAME").(Name.text() == folderName);
if (existXMLList.length() == 0)
{
folderDGDataXML.appendChild(new XML("<FOLDER_NAME><Name>"+item.FOLDER+"</Name></FOLDER_NAME>"));
}
var monthXMLList:XMLList = folderDataXML.descendants("SUMMARY_RECORD").(Name.text() == monthName);
if (monthXMLList.length() == 0)
{
folderDataXML.appendChild(new XML("<SUMMARY_RECORD><Name>"+item.MONTH+"</Name><COUNT>"+item.COUNT+"</COUNT></SUMMARY_RECORD>"));
}
else
{
monthXMLList..COUNT = Number(monthXMLList..COUNT) + Number(item.COUNT);
//If more than one node it throws error. you need to use loop operation
}
}
trace("folderDGDataXML" + folderDGDataXML);
trace("folderDataXML" + folderDataXML);

How convert stream excel file to datatable C#?

I use Epplus to reading xlsx files from stream.
It has a bug , it cant read some columns in my workbook.How can read xlsx files from stream to datatable without epplus ?
my older code:
public static DataSet ReadExcelFile(Stream stream)
{
try
{
//2. Reading from a OpenXml Excel file (2007 format; *.xlsx)
IExcelDataReader excelReader =
ExcelReaderFactory.CreateOpenXmlReader(stream);
//...
DataSet result = excelReader.AsDataSet();
return result;
}
catch (Exception x)
{
throw x;
}
}
I didnt report it, but i tried so much combinations.If there are empty columns in worksheet ,epplus reader cant read correctly column values.
"It has a bug , it cant read some columns in my workbook"
Can you describe the bug, have you reported it or is it already known, what version are you using?
Here's a simple approach to load an excel file into a DataTable with EPPlus.
public static DataTable getDataTableFromExcel(string path)
{
using (var pck = new OfficeOpenXml.ExcelPackage())
{
using (var stream = File.OpenRead(path))
{
pck.Load(stream);
}
var ws = pck.Workbook.Worksheets.First();
DataTable tbl = new DataTable();
bool hasHeader = true; // adjust it accordingly( i've mentioned that this is a simple approach)
foreach (var firstRowCell in ws.Cells[1, 1, 1, ws.Dimension.End.Column])
{
tbl.Columns.Add(hasHeader ? firstRowCell.Text : string.Format("Column {0}", firstRowCell.Start.Column));
}
var startRow = hasHeader ? 2 : 1;
for (var rowNum = startRow; rowNum <= ws.Dimension.End.Row; rowNum++)
{
var wsRow = ws.Cells[rowNum, 1, rowNum, ws.Dimension.End.Column];
var row = tbl.NewRow();
foreach (var cell in wsRow)
{
row[cell.Start.Column - 1] = cell.Text;
}
tbl.Rows.Add(row);
}
return tbl;
}
}
This is way past, however it could still help someone.
Apparently some columns in my worksheet were merged, so for example, if columns A and B are merged it only recognizes column A as the one with the value, and so it returns column B as empty, when i call on that particular cell's value(B). To get past this, make sure you know which cells are merged and then grab only the first one and regard the rest of the merged cells as null

Resources