I am using OpenXml to create Excel file and export table data. One of the scenario is I want a column to have dropdown of predefined values, say like true and false. I followed this question and wrote code as below
DataValidation dataValidation = new DataValidation
{
Type = DataValidationValues.List,
AllowBlank = true,
SequenceOfReferences = new ListValue<StringValue>() { InnerText = "B1" },
//Formula1 = new Formula1("'SheetName'!$A$1:$A$3") // this was used in mentioned question
Formula1 = new Formula1("True,False") // I need predefined values.
};
DataValidations dvs = worksheet.GetFirstChild<DataValidations>(); //worksheet type => Worksheet
if (dvs != null)
{
dvs.Count = dvs.Count + 1;
dvs.Append(dataValidation);
}
else
{
DataValidations newDVs = new DataValidations();
newDVs.Append(dataValidation);
newDVs.Count = 1;
worksheet.Append(newDVs);
}
If I use it with SheetName with cell values range, it works fine, but if I add string, it throws me error "Unreadable content found" and removes datavalidation node.
How to add values for list dropdown validation in formula itself. XML it creates for manually added(by editing in excel application) list values is <formula1>"One,Two"</formula1> (observed xml for excel file)
Okay I got this solved. Added escaped double quotes to formula and done.
DataValidation dataValidation = new DataValidation
{
Type = DataValidationValues.List,
AllowBlank = true,
SequenceOfReferences = new ListValue<StringValue>() { InnerText = "B1" },
Formula1 = new Formula1("\"True,False\"") // escape double quotes, this is what I was missing
};
DataValidations dvs = worksheet.GetFirstChild<DataValidations>(); //worksheet type => Worksheet
if (dvs != null)
{
dvs.Count = dvs.Count + 1;
dvs.Append(dataValidation);
}
else
{
DataValidations newDVs = new DataValidations();
newDVs.Append(dataValidation);
newDVs.Count = 1;
worksheet.Append(newDVs);
}
Related
I have a method which create an excel file (.xlsx) from a list of strings using DocumentFormat.OpenXml. The created file needs to be repaired when I try to open it with Excel 2016. When I click "Yes" Excel shows my file correctly.
Does anyone have any suggestions? Thanks in advance.
Here's my code:
private byte[] ExportDataXlsx(System.Data.Common.DbDataReader reader, string[] fields, string[] headers, string Culture) {
System.IO.MemoryStream sw = new System.IO.MemoryStream();
using (var workbook = Packaging.SpreadsheetDocument.Create(sw, SpreadsheetDocumentType.Workbook)) {
var sheetData = CreateSheet(workbook);
while (reader.Read()) {
Spreadsheet.Row newRow = new Spreadsheet.Row();
foreach (string column in fields) {
Spreadsheet.Cell cell = new Spreadsheet.Cell();
cell.DataType = Spreadsheet.CellValues.String;
object value = null;
try {
int index = reader.GetOrdinal(column);
cell.DataType = DbKymosDomainService.ToXlsType(reader.GetFieldType(index));
value = DbKymosDomainService.ToStringFromCulture(reader.GetValue(index), reader.GetFieldType(index), Culture);
if (cell.DataType == Spreadsheet.CellValues.Number){
value = value == null ? "" : value.ToString().Replace(",", ".");
}
}
catch { }
cell.CellValue = new Spreadsheet.CellValue(value == null ? null : value.ToString()); //
newRow.AppendChild(cell);
try { var x = newRow.InnerXml; } catch { newRow.RemoveChild(cell); }
}
sheetData.AppendChild(newRow);
}
workbook.Close();
}
byte[] data = sw.ToArray();
sw.Close();
sw.Dispose();
return data;
}
Function which create sheet:
private Spreadsheet.SheetData CreateSheet(Packaging.SpreadsheetDocument workbook)
{
var workbookPart = workbook.AddWorkbookPart();
workbook.WorkbookPart.Workbook = new Spreadsheet.Workbook();
workbook.WorkbookPart.Workbook.Sheets = new Spreadsheet.Sheets();
var sheetPart = workbook.WorkbookPart.AddNewPart<Packaging.WorksheetPart>();
var sheetData = new Spreadsheet.SheetData();
sheetPart.Worksheet = new Spreadsheet.Worksheet(sheetData);
Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<Spreadsheet.Sheets>();
string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart);
uint sheetId = 1;
if (sheets.Elements<Spreadsheet.Sheet>().Count() > 0) {
sheetId =
sheets.Elements<Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1;
}
Spreadsheet.Sheet sheet = new Spreadsheet.Sheet() { Id = relationshipId, SheetId = sheetId, Name = "Export" };
sheets.Append(sheet);
return sheetData;
}
In my experience when a file needs to be repaired after creating it using OpenXML it means that it is missing a crucial element or the crucial element is in the wrong place. I'm having difficulty following your code so that in itself points to something being in the wrong place. Code should be sequential and self-explanatory. A few pointers however to help with getting to the root cause of your issue.
I would suggest first using ClosedXML as it takes so much strain out of the coding.https://github.com/closedxml/closedxml
Debug your code and step through each step to see what's going on.
Open the created file in OpenXML Productivity Tool https://github.com/OfficeDev/Open-XML-SDK/releases/tag/v2.5 and have a look around.
Another tool that I couldn't be without is OpenXML FileViewer: https://github.com/davecra/OpenXmlFileViewer
Lastly I always run this sub routine to validate documents I create using OpenXML:
public static List<string> ValidateWordDocument(FileInfo filepath, ref Int32 maxerrors = 100)
{
try
{
using (WordprocessingDocument wDoc = WordprocessingDocument.Open(filepath.FullName, false))
{
OpenXmlValidator validator = new OpenXmlValidator();
int count = 0;
List<string> er = new List<string>()
{
string.Format($"Assessment of {filepath.Name} on {DateTime.Now} yielded the following result: {Constants.vbCrLf}")
};
// set at zero so that we can determine the total quantity of errors
validator.MaxNumberOfErrors = 0;
// String.Format("<strong> Warning : </strong>")
foreach (ValidationErrorInfo error in validator.Validate(wDoc))
{
count += 1;
if (count > maxerrors)
break;
er.Add($"Error {count}{Constants.vbCrLf}" + $"Description {error.Description}{Constants.vbCrLf}" + $"ErrorType: {error.ErrorType}{Constants.vbCrLf}" + $"Node {error.Node}{Constants.vbCrLf}" + $"Name {error.Node.LocalName}{Constants.vbCrLf}" + $"Path {error.Path.XPath}{Constants.vbCrLf}" + $"Part: {error.Part.Uri}{Constants.vbCrLf}" + $"-------------------------------------------{Constants.vbCrLf}" + $"Outer XML: {error.Node.OuterXml}" + $"-------------------------------------------{Constants.vbCrLf}");
}
int validatorcount = validator.Validate(wDoc).Count;
switch (validatorcount)
{
case object _ when validatorcount > maxerrors:
{
er.Add($"Returned {count - 1} as this is the Maximum Number set by the system. The actual number of errors in {filepath.Name} is {validatorcount}");
er.Add("A summary list of all error types encountered is given below");
List<string> expectedErrors = validator.Validate(wDoc).Select(_e => _e.Description).Distinct().ToList();
er.AddRange(expectedErrors);
break;
}
case object _ when 1 <= validatorcount && validatorcount <= maxerrors:
{
er.Add($"Returned all {validator} errors in {filepath.Name}");
break;
}
case object _ when validatorcount == 0:
{
er.Add($"No Errors found in document {filepath.Name}");
break;
}
}
return er;
wDoc.Close();
}
}
catch (Exception ex)
{
Information.Err.MessageElevate();
return null;
}
}
It helps greatly with problem solving any potential issues.
I am trying to generate a chart for a powerpoint slide using C#.net. The chart works perfectly when I hard code the data, so my goal here is to be able to populate the excel backend from my applications datatable. What i need help with is defining the data ranges(see below)
var areaworkbook = (EXCEL.Workbook)areachart.ChartData.Workbook;
areaworkbook.Windows.Application.Visible = false;
var dataSheet2 = (EXCEL.Worksheet)areaworkbook.Worksheets[1];
var sc2 = areachart.SeriesCollection();
dataSheet1.Cells.Range["A2"].Value2 = "Name 1";
dataSheet1.Cells.Range["A3"].Value2 = "Name 2";
dataSheet1.Cells.Range["A4"].Value2 = "Name 3";
dataSheet1.Cells.Range["A5"].Value2 = "Name 4";
dataSheet1.Cells.Range["B2"].Value2 = Value 1;
dataSheet1.Cells.Range["B3"].Value2 = value 2;
dataSheet1.Cells.Range["B4"].Value2 = value 3;
dataSheet1.Cells.Range["B5"].Value2 = value 4 ;
var series2 = sc2.NewSeries();
series2.Name = "Series 2";
series2.XValues = "'Sheet1'!$A$2:$A$5";
series2.Values = "'Sheet1'!$C$2:$C$5";
series2.ChartType = Office.XlChartType.xlAreaStacked;
areachart.HasTitle = true;
areachart.ChartTitle.Font.Bold = true;
areachart.ChartTitle.Font.Italic = true;
areachart.ApplyLayout(4);
areachart.Refresh();
How will I dynamically add A6, A7, A8... until my datatable is complete?
Just use a loop and calculate the cell address. For the sake of argument, I'm going to assume the data is coming from a Linq query, though you could get it any other way.
int row = 2; // You expect to start here
foreach (var data in db.MyData().Where(... whatever you need here ...))
{
dataSheet1.Cells.Range["A" + row].Value2 = data.Name;
dataSheet1.Cells.Range["B" + row].Value2 = data.Value;
row++;
}
series2.XValues = "'Sheet1'!$A$2:$A$" + row;
series2.Values = "'Sheet1'!$C$2:$C$" + row;
I am trying to achieve the following: I have a C# application which does some data processing and then outputs to a .xlsx using EPPlus. I want to add some conditional formatting to the excel and tried the following method, first I made a template blank excel with all conditional formatting rules set up and then tried dumping the data in it. The snippet below is my approach. p is an Excel package. Currently this does not work, the data is written correctly however the formatting rules that I set up are lost. I'm guessing because it basically clears everything before writing. Any help will be appreciated!
Byte[] bin = p.GetAsByteArray();
File.Copy("C:\\template.xlsx", "C:\\result.xlsx");
using (FileStream fs = File.OpenWrite("C:\\result.xlsx")) {
fs.Write(bin, 0, bin.Length);
}
Note :: I tried the following as well to avoid the whole external template situation.. check snippet below. The problem with this is that, after the .xlsx is generated and I open it, it says the file has unreadable or not displayable content and that it needs to repair it and after I do that, everything is fine and the conditional formatting has also worked. I have no clue why its doing that or how I can get rid of the error upon file opening.
string _statement = "$E1=\"3\"";
var _cond = ws.ConditionalFormatting.AddExpression(_formatRangeAddress);
_cond.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
_cond.Style.Fill.BackgroundColor.Color = Color.LightCyan;
_cond.Formula = _statement;
Any help will be appreciated!!
The method of using fs.Write will simply overwrite the copied file with the epplus generated file since you are doing it at the byte/stream level. So that will not get you what you want. (#MatthewD was showing you this in his post).
As for applying the format itself, what you have should work but if you are getting that kind of error I suspect you are mixing epplus and non-epplus manipulation of the excel file. This is how you should be doing it roughly:
[TestMethod]
public void Conditional_Format_Test()
{
//http://stackoverflow.com/questions/31296039/conditional-formatting-using-epplus
var existingFile = new FileInfo(#"c:\temp\temp.xlsx");
if (existingFile.Exists)
existingFile.Delete();
//Throw in some data
var datatable = new DataTable("tblData");
datatable.Columns.Add(new DataColumn("Col1", typeof(int)));
datatable.Columns.Add(new DataColumn("Col2", typeof(int)));
datatable.Columns.Add(new DataColumn("Col3", typeof(int)));
for (var i = 0; i < 20; i++)
{
var row = datatable.NewRow();
row["Col1"] = i;
row["Col2"] = i * 10;
row["Col3"] = i * 100;
datatable.Rows.Add(row);
}
using (var pack = new ExcelPackage(existingFile))
{
var ws = pack.Workbook.Worksheets.Add("Content");
ws.Cells["E1"].LoadFromDataTable(datatable, true);
//Override E1
ws.Cells["E1"].Value = "3";
string _statement = "$E1=\"3\"";
var _cond = ws.ConditionalFormatting.AddExpression(new ExcelAddress(ws.Dimension.Address));
_cond.Style.Fill.PatternType = ExcelFillStyle.Solid;
_cond.Style.Fill.BackgroundColor.Color = Color.LightCyan;
_cond.Formula = _statement;
pack.SaveAs(existingFile);
}
}
To expand on #Ernie code sample, here's a working example that colors a range according to cell's value. Each cell of the range can have any of three colors depending on the cell's value (<.01, <.05, <.1).
ExcelRange rng = ws.Cells[statsTableRowStart, 10, statsTableRowStart + gud.levels.level.Count() - 1, 10];
OfficeOpenXml.ConditionalFormatting.Contracts.IExcelConditionalFormattingExpression _condp01 = ws.ConditionalFormatting.AddExpression(rng);
_condp01.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
_condp01.Style.Fill.BackgroundColor.Color = System.Drawing.Color.OrangeRed;
_condp01.Formula = new ExcelFormulaAddress(rng.Address) + "<.01";
OfficeOpenXml.ConditionalFormatting.Contracts.IExcelConditionalFormattingExpression _condp05 = ws.ConditionalFormatting.AddExpression(rng);
_condp05.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
_condp05.Style.Fill.BackgroundColor.Color = System.Drawing.Color.OliveDrab;
_condp05.Formula = new ExcelFormulaAddress(rng.Address) + "<.05";
OfficeOpenXml.ConditionalFormatting.Contracts.IExcelConditionalFormattingExpression _condp1 = ws.ConditionalFormatting.AddExpression(rng);
_condp1.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
_condp1.Style.Fill.BackgroundColor.Color = System.Drawing.Color.LightCyan;
_condp1.Formula = new ExcelFormulaAddress(rng.Address) + "<.1";
Does anybody know how to set print area through OpenXML SDK in Excel?
I've tried using the following code:
public void XLUpdateDefinedName(string fileName, string definedName, string newRange)
{
using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, true))
{
WorkbookPart wbPart = document.WorkbookPart;
var definedNames = wbPart.Workbook.Descendants<DefinedNames>().FirstOrDefault();
DefinedName name = definedNames.Descendants<DefinedName>().Where(m => m.Name == definedName).Single();
UInt32Value locSheetId = name.LocalSheetId;
name = null;//.Remove();
wbPart.Workbook.Save();
name = new DefinedName() { Name = definedName, LocalSheetId = locSheetId , Text = newRange}
;
wbPart.Workbook.Save();
//newDefinedName.Text = newRange;
//definedNames.Append(newDefinedName);
}
}
UPDATE:
I continue to receive an error from excel saying there is unreadable content in file with the following code.
public void XLUpdateDefinedName(string fileName, string definedName, string newRange, string sheet, UInt32Value localId)
{
using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, true))
{
String sheetName = sheet;
string topLeft = newRange.Split(':').First();
string bottomRight = newRange.Split(':').Last();
WorkbookPart wbPart = document.WorkbookPart;
var definedNames = wbPart.Workbook.Descendants<DefinedNames>().FirstOrDefault();
var nameCollection = definedNames.Descendants<DefinedName>().Where(m => m.Text.StartsWith(sheetName));
DefinedName name = nameCollection.Count() > 0 ? nameCollection.First() : null;
UInt32Value locSheetId;
if (name != null)
{
locSheetId = name.LocalSheetId;
name.Remove();
wbPart.Workbook.Save();
}
else
{
locSheetId = localId;
}
name = new DefinedName() { Name = "_xlnm.Print_Area", LocalSheetId = locSheetId};
name.Text = String.Format("{0}!{1}:{2}", sheetName,topLeft,bottomRight);
definedNames.Append(name);
wbPart.Workbook.Save();
}}
newRange is of the form ( $A$10:$C$15 )
I've found some information about a method that seems not to be using Interop. You can try something like:
//load the work book
...
myWorkBook.Worksheets.First().PageSetup.PrintAreas.Add("A1:F40");
//save the workbook
//...
See if this helps. I haven't tried it myself yet, but I'm going to verify it.
UPDATE:
The first method seems to require an additional library. You can get it from here:
http://closedxml.codeplex.com/. I haven't used it myself, so I cannot assure you it works correctly.
Pure OpenXML solution
I've managed to change the print area by manually modifying the xlsx file contents in notepad editor.
In C# you should try to use the follwoing method (it sets printing area to A1:G19):
//first you need to get reference to your workbook, but I assume you already have this
//...
//then you can add an information about desired print area
DefinedNames definedNames = new DefinedNames();
DefinedName printAreaDefName = new DefinedName() { Name = "_xlnm.Print_Area", LocalSheetId = (UInt32Value)0U };
printAreaDefName.Text = "Worksheet1!$A$1:$G$19";
definedNames.Append(printAreaDefName);
//then you should append the created element to your workbook
//...
workbook1.Append(definedNames);
The thing you need to change is line: printAreaDefName.Text = "Worksheet1!$A$1:$G$19";.
You should change the Text value to contain information in format: [worksheet_name]![top-left corner of print area]:[bottom-right corner of print area]. It should set your print area to a rectangle with upper-left and bottom-right corners as specified.
If you want to specify print areas for different worksheets, try to add multiple DefinedName objects:
DefinedName printAreaDefName = new DefinedName() { Name = "_xlnm.Print_Area", LocalSheetId = (UInt32Value)0U };
printAreaDefName.Text = "Worksheet1!$A$1:$G$19";
definedNames.Append(printAreaDefName);
DefinedName printAreaDefName2 = new DefinedName() { Name = "_xlnm.Print_Area", LocalSheetId = (UInt32Value)1U };
printAreaDefName2.Text = "Worksheet2!$B$1:$H$23";
definedNames.Append(printAreaDefName2);
DefinedName printAreaDefName3 = new DefinedName() { Name = "_xlnm.Print_Area", LocalSheetId = (UInt32Value)2U };
printAreaDefName3.Text = "Worksheet3!$A$1:$J$10";
definedNames.Append(printAreaDefName3);
I also recommend using OpenXML SDK 2.0 Productivity Tool. It allows you to show the contents of a chosen OpenXML file, compare files, validate a file and even show a C# code that you would write in order to recreate the file programatically :).
You can download it from here:
http://www.microsoft.com/download/en/details.aspx?id=5124
UPDATE II:
I've corrected a mistake in format of the print area value string. Sorry for the confusion.
I've also took the code you posted and created a method based on it. It works correctly and after modifying the print area I can open the file in Excel without issues. The code assumes that a print range is already defined and you are now just changing it, but it can be modified to add new print range as well.
Here's the code:
private void OpenXmlFileHandling(String fileName)
{
using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, true))
{
//some sample values
String definedName = "Worksheet3";
String topLeft = "$A$3";
String bottomRight = "$D$7";
WorkbookPart wbPart = document.WorkbookPart;
var definedNames = wbPart.Workbook.Descendants<DefinedNames>().FirstOrDefault();
var namesCollection = definedNames.Descendants<DefinedName>().Where(m => m.Text.StartsWith(definedName));
DefinedName name = namesCollection != null ? namesCollection.First() : null;
UInt32Value locSheetId;
//we assume that name is not null, because print range for this worksheet was defined in the source template file
//if name was null, we should probably just assign to locSheetId a number definedNames.Count() + 1 and not remove the name node
locSheetId = name.LocalSheetId;
name.Remove();
wbPart.Workbook.Save();
name = new DefinedName() { Name = "_xlnm.Print_Area", LocalSheetId = locSheetId, Text = String.Format("{0}!{1}:{2}", definedName, topLeft, bottomRight) };
definedNames.Append(name);
wbPart.Workbook.Save();
}
}
I put the values of worksheet name and print area range inside the method, so you can see what kind of values they should have. I hope this helps.
Let me explain my case: I have excel workbook with following sheets (T1,I1,M1). Now my requirement was based on some condition T1,I1,M1 will be copied to same excel workbook multiple times e.g. T2,I2,M2, T3,I3,M3 and so on. For me I2,M2 did not have any issues with Print area but for copied sheet T2,T3... had issue. since it had huge data. excel column goes upto "AG". So here is what i did in code
Once the new sheet is added to workbook
sheets.Append(copiedSheet);
first get the current sheet count
var count = sheets.Count();
Get the sheet count, this will be used in LocalsheetId as printarea setting.
Only for copied techical sheet the print area was not set properly. Hence need to be set correctly.
DefinedName printAreaDefName = new DefinedName() { Name = "_xlnm.Print_Area", LocalSheetId = Convert.ToUInt32(count) };
Be care full with defName.Text the format is 'T1'!$A$1:$AG$19
printAreaDefName.Text = "'" + copiedSheet.Name + "'!$A$1:$AG$22";
workbookPart.Workbook.DefinedNames.Append(printAreaDefName);
workbookPart.Workbook.Save();
There was no need for me to add new Definedname in DefinedNames collection. So I just added to workbook definedNames collection and it worked.
string Code = "";
if (fileUp.HasFile)
{
string Path = fileUp.PostedFile.FileName;
// initialize the Excel Application class
ApplicationClass app = new ApplicationClass();
// create the workbook object by opening the excel file.
Workbook workBook = app.Workbooks.Open(Path, 0, true, 5, "", "", true,
XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
// Get The Active Worksheet Using Sheet Name Or Active Sheet
Worksheet workSheet = (Worksheet)workBook.ActiveSheet;
int index = 0;
// This row,column index should be changed as per your need.
// that is which cell in the excel you are interesting to read.
object rowIndex = 2;
object colIndex1 = 1;
object colIndex2 = 2;
object colIndex3 = 3;
object colIndex4 = 4;
object colIndex5 = 5;
object colIndex6 = 6;
object colIndex7 = 7;
try
{
while (((Range)workSheet.Cells[rowIndex, colIndex1]).Value2 != null)
{
rowIndex = 2 + index;
//string QuestionCode = (index + 1).ToString();
string QuestionCode = ((Range)workSheet.Cells[rowIndex, colIndex1]).Value2.ToString();
string QuestionText = ((Range)workSheet.Cells[rowIndex, colIndex2]).Value2.ToString();
string CorrectAnswer = ((Range)workSheet.Cells[rowIndex, colIndex3]).Value2.ToString();
string ChoiceA = ((Range)workSheet.Cells[rowIndex, colIndex4]).Value2.ToString();
string ChoiceB = ((Range)workSheet.Cells[rowIndex, colIndex5]).Value2.ToString();
string ChoiceC = ((Range)workSheet.Cells[rowIndex, colIndex6]).Value2.ToString();
string ChoiceD = ((Range)workSheet.Cells[rowIndex, colIndex7]).Value2.ToString();
// string ChoiceE = ((Excel.Range)workSheet.Cells[rowIndex, colIndex7]).Value2.ToString();
newQuestionElement = new XElement("Question");
XElement optionElement = new XElement(QuestionElement.Option);
questionType = ddlQusType.SelectedValue.ToByte();
if (!string.IsNullOrEmpty(QuestionText))
newQuestionElement.Add(new XElement(QuestionElement.QuestionText, QuestionText));
else
{
//lblMessage.Text = "Missing question in Qus No.: " + i;
break;
}
newQuestionElement.Add(new XElement(QuestionElement.QuestionType, questionType));
//newQuestionElement.Add(new XElement(QuestionElement.Randomize, chbRandomizeChoice.Checked));
newQuestionElement.Add(new XElement(QuestionElement.Answer, CorrectAnswer));
if (ChoiceA.Trim() != string.Empty)
optionElement.Add(new XElement("A", ChoiceA));
if (ChoiceB.Trim() != string.Empty)
optionElement.Add(new XElement("B", ChoiceB));
if (ChoiceC.Trim() != string.Empty)
optionElement.Add(new XElement("C", ChoiceC));
if (ChoiceD.Trim() != string.Empty)
optionElement.Add(new XElement("D", ChoiceD));
newQuestionElement.Add(optionElement);
index++;
saveData(QuestionCode.ToString());
I am using this code to retrieve the data from .xlsx file.
But if the file has any special characters in it, it is showing it as different, like so
The set S = {1,2,33……….12} is to be partitioned into three sets
A,B,C of equal size. Thus, `A U B U C = S,`
The set S = {1,2,33……….12} is to be partitioned into three sets
A,B,C of equal size. Thus, `A È B È C = S,`
Looks like an encoding issue.
I use to have this issue after reading Excel into a data table and then serializing the data table to a file.
Every time I would read the data back in from the serialized file, some symbols would be replaced with funny A's and E's.
I discovered the problem was with the encoding I was using. I then started to store excel data using Unicode encoding and have never encounter another symbol problem with Excel data again.
I hope this helps...