I am reading in cell values in an Excel worksheet, and the text often has special formatting such as superscript and subscript. I would like to preserve this formatting when bringing it into my C# application, using the strings for various labels and such. However, with my current implementation, all superscript and subscript characters lose that formatting. I believe it has to do with the fact that I cast things to different types throughout the process:
const string fileName = "C:\\Users\\J.Smith\\Desktop\\FeatureInfoPropertyAttributesEXCEL.xlsx";
// Prepare the required items
Workbook wb = null;
// Start Excel
Application excel = new Application {Visible = false};
try
{
// Open file
Workbook wb = excel.Workbooks.Open(fileName);
// Read sheets
Sheets sheets = wb.Worksheets;
// Select sheet
Worksheet ws = (Worksheet) sheets.Item["FeatureInfoPropertyAttributes"];
string firstCellForPropertiesRange = "A2";
string secondCellForPropertiesRange = ws.Range[firstCellForPropertiesRange].End[XlDirection.xlDown].Address;
string firstCellForHeadersRange = firstCellForPropertiesRange.Replace("A", "B");
string secondCellForHeadersRange = secondCellForPropertiesRange.Replace("A", "B");
string firstCellForProposedHeadersRange1 = firstCellForHeadersRange.Replace("B", "C");
string secondCellForProposedHeadersRange1 = secondCellForHeadersRange.Replace("B", "C");
string firstCellForProposedHeadersRange2 = firstCellForProposedHeadersRange1.Replace("C", "D");
string secondCellForProposedHeadersRange2 = secondCellForProposedHeadersRange1.Replace("C", "D");
Range propertiesRange = ws.Range[firstCellForPropertiesRange, secondCellForPropertiesRange];
Range headersRange = ws.Range[firstCellForHeadersRange, secondCellForHeadersRange];
Range proposedHeadersRange1 = ws.Range[firstCellForProposedHeadersRange1, secondCellForProposedHeadersRange1];
Range proposedHeadersRange2 =
ws.Range[firstCellForProposedHeadersRange2, secondCellForProposedHeadersRange2];
List<string> properties =
propertiesRange.Cells.Cast<object>()
.Select((t, i) => ((Range) propertiesRange.Cells[i + 1]).Value2 ?? string.Empty)
.Cast<string>()
.ToList();
List<string> existingHeaders =
headersRange.Cells.Cast<object>()
.Select((t, i) => ((Range) headersRange.Cells[i + 1]).Value2 ?? string.Empty)
.Cast<string>()
.ToList();
List<string> proposedHeaders1 =
proposedHeadersRange1.Cells.Cast<object>()
.Select(
(t, i) =>
((Range) proposedHeadersRange1.Cells[i + 1]).Value2 ?? string.Empty)
.Cast<string>()
.ToList();
List<string> proposedHeaders2 =
proposedHeadersRange2.Cells.Cast<object>()
.Select(
(t, i) =>
((Range)proposedHeadersRange2.Cells[i + 1]).Value2 ?? string.Empty)
.Cast<string>()
.ToList();
foreach (string s in proposedHeaders1.Where(s => !s.Equals(string.Empty)))
{
Console.WriteLine(s);
}
foreach (string s in proposedHeaders2.Where(s => !s.Equals(string.Empty)))
{
Console.WriteLine(s);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
excel.Visible = true;
wb.Close(false, null, null);
excel.Quit();
}
Does C# strings support such formatting characteristics as superscript and subscript in strings?
If the answer to the first question is 'yes', how would I go about accomplishing this?
You can get the superscript/subscript information from Excel via the logical flags in the Font Property
of the given Range
:
Range curRange = ws.get_Range("A1");
if(curRange.Font.Superscript)
{
//It is a superscript
}
if(curRange.Font.Subscript)
{
//It is a subscript
}
The easiest way to represent this in C# winforms is relying on a RichTextBox
(you can even make it "look like a label", as suggested in the following link) and on its SelectionCharOffset
. With Labels
, it is not so straightforward but there are some workarounds.
---------- UPDATE
ANSWER TO THE FIRST QUESTION:
C# supports formatting through its Objects
, not its string type
. Excel strings
do not support formatting either; the Ranges
are the ones in charge of dealing with this.
ANSWER TO THE SECOND QUESTION:
You can replicate in C# what Excel Cells
/Ranges
do by relying on the corresponding C# equivalent, that is: Controls
/Objects
. The Control
meant for text-decoration is the RichTextBox
and thus it is the best equivalent in this case. Nonetheless, there are different ways to deliver the result you want by using other Controls
, as explained above.