open xml, set cellvalue html string - c#

Technologies: C#, openxml
I am trying to create xlsx file using opennxml document. Data table contains one column with rich text in html string. example "hi" or hi
How to append/set value to cellValue.Text. Please suggest any other approach to achieve this.
Cell cell = new Cell() { CellReference = ExcelHelper.ColumnCaption.Instance.Get((Convert.ToInt32((UInt32)rowIndex) - 2), cIndex), DataType = CellValues.InlineString };
cell.DataType = new EnumValue<CellValues>(CellValues.String);
CellValue cellValue = new CellValue();
cellValue.Text = data.Rows[rIndex][cIndex].ToString();//<b>hi</b>
cell.Append(cellValue);

Related

C# unable to update spreadsheet table header values dynamically

I have a spreadsheet template which has a table (Table inserted into sheet from Insert tab) and when the user clicks on the export button these header values of the table should be updated by new values dynamically. For this I'm using c# and DocumentFormat.OpenXml library.
After exporting header values are getting updated in the spreadsheet table but when I open the excel document it says "We found problem with some content in '<>.xlsx' . Do you want us to recover as much as we can ? ".
Also, when I tried updating table rows other than header row, I wasn't getting above popup.
I have tried below approaches to update table header values.
Approach 1
using (SpreadsheetDocument document = SpreadsheetDocument.Open("test.xlsx", true))
{
WorkbookPart wbPart = document.WorkbookPart;
Sheet sheet = wbPart.Workbook.Descendants<Sheet>().Where(s => s.name =="Sheet1").FirstOrDefault();
WorksheetPart wsPart = (WorksheetPart) (wbPart.GetPartById(sheet.Id));
WorkSheet wSheet = wsPart.WorkSheet;
Row row = wSheet.Elements<Row>().Where(r => r.RowIndex ==1 ).FirstOrDefault();
Cell cell = row.Elements<Cell>().Where(c => string.Compare
(c.CellReference.Value, "A1" , true) == 0).First();
cell.CellValue = new CellValue("new Header");
cell.DataType = CellValues.String;
wbPart.WorkBook.save();
}
Approach 2
foreach(TableDefinitionPart tdp in wsPart.TableDefinitionParts )
{
QueryTablePart qtp= tdp .QueryTableParts.FirstOrDefault();
Table excelTable = tdp .Table;
int i = 0;
foreach(TableColumn col in excelTable.TableColumns)
{
col.name.Value = "Header"+i;
i++;
}
}

Set Multiple styles in a single excel cell using OfficeOpenXml in C#

I cannot find a way to style a single excel cell in different styles.
For example I need to make only some part of the string bold and leave the rest unbold in one cell.
I can only access Cells not characters in OpenXml.
Usually what I do to style the cell is,
ExcelPackage package = new ExcelPackage();
ExcelWorksheet ws = package.Workbook.Worksheets.Add("SheetName");
ws.Cells[1, 1].Style.Font.Bold = true;
I can't find a way to access characters in a cell. I saw some other excel plugins do the same but Is there any way OpenXml can do this? Any suggestions will be great. Thanks
The answer here works well.
You have to add the cell content as separate ExcelRichText objects.
Example:
ExcelRichText rt1 = ws.Cells[1, 1].RichText.Add("AB");
rt1.Bold = true; // bold just the "AB"
ExcelRichText rt2 = ws.Cells[1, 1].RichText.Add("CD");
Output will be: "ABCD"
Note: You will need to reference the namespace OfficeOpenXml.Style
This is how you can add partial styles in an excel sheet using OpenXML.
//Partial Cell Styling
uint currentRow = 2;
Row newRow = new Row() { RowIndex = currentRow };
//create a new inline string cell
Cell cell = new Cell() { CellReference = "J" + currentRow.ToString() };
cell.DataType = CellValues.InlineString;
//create a run for the bold text
Run run1 = new Run();
run1.Append(new Text("By: "));
//create a second run for the non-bod text
Run run2 = new Run();
run2.Append(new Text(Environment.NewLine + " SAHIL VIG") { Space = SpaceProcessingModeValues.Preserve });
//create runproperties and append a "Bold" to them
RunProperties run2Properties = new RunProperties();
run2Properties.Append(new Bold());
//set the first runs RunProperties to the RunProperties containing the bold
run2.RunProperties = run2Properties;
//create a new inline string and append both runs
InlineString inlineString = new InlineString();
inlineString.Append(run1);
inlineString.Append(run2);
//append the inlineString to the cell.
cell.Append(inlineString);
//append the cell to the row
newRow.Append(cell);
sheetData.Append(newRow);

Setting Font.Bold and Column.Width for Cells in OPEN XML

I've been using OPEN XML to create a spread sheet which can then be downloaded. I want to set the column widths and also change the header to bold. I've done this using Office.Interop.Excel but I'm struggling with this format. My code is below, you can see I've set up a font but have been unable to assign it to my spread sheet, I have got messages saying it's not possible to assign to a tree.
SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(fileName, SpreadsheetDocumentType.Workbook); //Open(fileName, true);
try
{
WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook();
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(new SheetData());
DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>(new DocumentFormat.OpenXml.Spreadsheet.Sheets());
Sheet sheet = new Sheet() { Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Models" };
sheets.Append(sheet);
DocumentFormat.OpenXml.Spreadsheet.Font boldFont = new DocumentFormat.OpenXml.Spreadsheet.Font();
Bold bFontBold = new Bold();
boldFont.Append(bFontBold);
DocumentFormat.OpenXml.Spreadsheet.Worksheet worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet();
SheetData sheetData = new SheetData();
........
Row row = new Row();
Cell cell = new Cell()
{
CellReference = "A" + (intI + 1),
DataType = CellValues.String,
CellValue = new CellValue(ModelBookrowDetail[0])
};
row.Append(cell);
Cell cell2 = new Cell()
{
CellReference = "B" + (intI + 1),
DataType = CellValues.String,
CellValue = new CellValue(ModelBookrowDetail[1])
};
row.Append(cell2);
.........
sheetData.Append(row);
}
worksheet.Append(sheetData);
worksheetPart.Worksheet = worksheet;
spreadsheetDocument.Close();
}
catch
{
spreadsheetDocument.Close();
}
I don't know how set you are on using OpenXml. I might suggest looking into ClosedXml. Up until now it has saved me a lot of manhours. It only has one downside to it, and that is that it doesn't manage Word documents like OpenXml does.
ClosedXml is a more object oriented Open Source Library, and is far more well documented in contrast to what i have experienced with OpenXml.
You can find ClosedXml here:
https://github.com/ClosedXML/ClosedXML
Best of luck
Olliver

How to get value shown in cell from .xlsx using open XML C#

Im new to C# and open XML, so please be patient with my ingnorance.
I have this problem:
I need to get cell value from .xlsx file. I can do that using XlGetCellValue method.
But When one cell (for example A2 from sheet1) gets it value from another cell (B2 sheet2)
XlGetCellValue("", "Sheet1", "A2")
returns Sheet2!B2Joe.
Or when the cell contains computation (like =C2+D2), XlGetCellValue(...) returns C2+D2120
Is there any easy way to get just value "Joe" and "120?
Here the link to MSDN on how to get the value of a cell using the Open XML SDK 2.5. There is a code sample provided.
How to: Retrieve the values of cells in a spreadsheet document (Open XML SDK)
Working with openxmnl could be a pain in the ass if you haven't yet downloaded OpenXMLSDKToolV25.msi (Productivity tool).
basically it's a reflection tool. you can open an excel document and the tool create all code you need to build the same from scratch.
CellValue it's only for value. using formula you have to deal with cell formula.
Eg. I created an excel file in A1 = 1256 in B1 = 2 in C1 "=A1*B1"
Opening the file with OpenXMLSDKTool i got:
public Row GenerateRow()
{
Row row1 = new Row(){ RowIndex = (UInt32Value)1U, Spans = new ListValue<StringValue>() { InnerText = "1:3" } };
Cell cell1 = new Cell(){ CellReference = "A1" };
CellValue cellValue1 = new CellValue();
cellValue1.Text = "1256";
cell1.Append(cellValue1);
Cell cell2 = new Cell(){ CellReference = "B1" };
CellValue cellValue2 = new CellValue();
cellValue2.Text = "2";
cell2.Append(cellValue2);
Cell cell3 = new Cell(){ CellReference = "C1" };
CellFormula cellFormula1 = new CellFormula();
cellFormula1.Text = "A1*B1";
CellValue cellValue3 = new CellValue();
cellValue3.Text = "2512";
cell3.Append(cellFormula1);
cell3.Append(cellValue3);
row1.Append(cell1);
row1.Append(cell2);
row1.Append(cell3);
return row1;
}
from this you can notice that CellValue and CellFormula are both childs of Cell.
So, assuming you can retrieve your Row r you can have this:
Cell c = r.Elements<Cell>().ElementAt(2);
CellValue cv = c.CellValue;
CellFormula cf = c.CellFormula;

What is the difference between CellValues.InlineString and CellValues.String in OpenXML?

I am trying to write some code to generate an Excel spreadsheet and I am not sure what the difference between CellValues.InlineString and CellValues.String to insert text on the cells.
Shall I use this:
private void UpdateCellTextValue(Cell cell,string cellValue)
{
InlineString inlineString = new InlineString();
Text cellValueText = new Text { Text = cellValue };
inlineString.AppendChild(cellValueText);
cell.DataType = CellValues.InlineString;
cell.AppendChild(inlineString);
}
this
private void UpdateCellTextValue(Cell cell, string cellValue)
{
cell.CellValue = new CellValue(cellValue);
cell.DataType = new EnumValue<CellValues>(CellValues.String);
}
or just this (InsertSharedStringItem returns the Id of the newly inserted shared string item)
private void SetCellSharedTextValue(Cell cell,string cellValue)
{
int stringId = InsertSharedStringItem(cellValue);
cell.CellValue = new CellValue(stringId.ToString());
cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
}
According to the documentation at 18.18.11 ST_CellType:
str (String) Cell containing a formula
string.
You will only want to use the CellValues.String when you are inserting a formula in the cell. Here is how the XML should look:
<x:c r="C6" s="1" vm="15" t="str">
<x:f>CUBEVALUE("xlextdat9 Adventure Works",C$5,$A6)</x:f>
<x:v>2838512.355</x:v>
</x:c>
CellValues.InlineString should only be used if you don't want to store the string in the SharedStringTable. Then anything you mark as an inlineString will be treated as rich text. Although note that when you use CellValues.InlineString that your text must be surounded by a text element and <is> tag:
<x:c r="B2" t="inlineStr">
<is><t>test string</t></is>
</c>

Categories