OPENXML. How to apply multiple paragraph properties in a single run - c#

Is there any way to create the Paragraph , run it and apply multiple properties in a single statemement instead of creating 'RunProperties' and append the the styles on by one.
In the example I am trying to add a second style - Font size like that but it doesn't work.
TableCell tc1_1 = new TableCell();
tc1_1.Append(new TableCellProperties(new TableCellWidth() { Type = TableWidthUnitValues.Dxa, Width = "5500" }));
tc1_1.Append(new Paragraph(new Run(
new Text("Test Company Name 123123123 123123"),
new FontSize() { Val = "8" }
)));

The issue is that you are creating invalid Open XML markup. For example, if you want to specify the font size for a specific run, this needs to be done by adding the FontSize instance to a RunProperties instance (i.e., w:rPr element).
My general recommendation is to look at Open XML markup created by Microsoft Word for what you want to have in your document, e.g., a table cell with some paragraphs and runs formatted in a certain way. You can then mimic in your code what Word has created.

Related

ClosedXml C# Overwriting existing style of excel file when new data are inserted for a range

I am trying to insert new data, but whenever I put new data then existing styles of my template are overwritten making them default ones. The background style of cells is replaced to default white color.
public IWorkbookBuilderSheetOperation Insert<T>(IEnumerable<T[]> rows, int firstCellRow, int firstCellColumn)
{
_currentSheet.IsSelected();
var lastCell = CalculateLastCell(rows, firstCellRow, firstCellColumn);
var range = _currentSheet!.Range(firstCellRow, firstCellColumn, lastCell.lastCellRow, lastCell.lastCellColumn);
_ = range.Cell(1, 1).InsertData(rows);
return this;
}
How can I keep existing styles when I read a template file and modify it.
If you can use an Excel table, it will keep a uniform look no matter how many rows you insert using the methods on IXLTable.
If you can't use a table and you need to keep using cell.InsertData(), then you could still manually copy the .Style of the old range to where you want it.

FlowDocument BreakPageBefore property not working on Table Block

So I'm dynamically creating a FlowDocument by using code (based on this MSDN article on How to build a table programatically).
The FlowDocument contains a number of blocks including paragraphs and tables. The tables being generated are of varying sizes and some are nested amongst other blocks. If a table can't fit on the remaining space on a page, I want to start that table at the beginning of the next page.
I am doing this by recording the current page when creating a particular block and then when the table has been finished, if I am on a new page, I set the BreakPageBefore property to true. Something like this:
foreach (var item in Data)
{
Table table = new Table();
flowDoc.Blocks.Add(table);
paginatorSource.DocumentPaginator.ComputePageCount();
pagecount = paginatorSource.DocumentPaginator.PageCount;
//do some work populating the table details...
TableColumn t = new TableColumn(); //etc...
paginatorSource.DocumentPaginator.ComputePageCount();
int newPagecount = paginatorSource.DocumentPaginator.PageCount;
if (newPagecount != pagecount)
{
//The table has spanned a new page so set the page break!
table.BreakPageBefore = true;
}
}
But this doesn't appear to work. However, if I wrap the table in a Section and set the BreakPageBefore on the section, it works fine. Also, If I have a Paragraph just before the table, I can set the BreakPageBefore on the Paragraph and that also works fine.
I have tried creating a simple FlowDocument that just has a bunch of repeating tables and that doesn't make any difference and I still have to wrap them in a Section.
They all inherit from Block So why won't it work on the Table directly?

Dynamic PDF Row Mockup

I have a small problem and the answer is probably really obvious and simple, but I guess I have failed in searching the internet for an answer, so once again I came to you guys.
I'm dynamically generating a PDF file in asp.net with c#, and right now I'm just making the base for it. One of the things it generates is a table in which a cart content should be revealed (yes I'm talking about an invoice) and I'm trying to give the table some mockup, but the mock up for the upper row will be different than the rest. (the header in which the columns are defined (Quantity, Title, Unit Price, Discount and Total)
Here's some code (it's the first time I did this so don't yell at me xD)
PdfPCell Quantity = new PdfPCell(new Phrase("Quantity"));
PdfPCell Title = new PdfPCell(new Phrase("Title"));
PdfPCell UniPr = new PdfPCell(new Phrase("Unit Price"));
PdfPCell Disc = new PdfPCell(new Phrase("Discount"));
PdfPCell Total = new PdfPCell(new Phrase("Total"));
PdfPCell[] cartheaderc = { Quantity, Title, UniPr, Disc, Total };
PdfPRow cartheader = new PdfPRow(cartheaderc);
So I've tried it this way and then say:
PdfPRow.BackgroundColor = new BaseColor(255,0,0);
Since that works for cells, I thought this might make sense, but apparently it didn't. I probably can do it when I take each cell apart, but there should be an easier way, right?
That's one problem, but sadly enough, I've got one more (although 10x more stupid and 10x easier). The color I want to use is #c5c5c5, but it doesn't want to recognize the color code.
Here is a list of the systems for ItextSharp I'm using (this is beside the standard systems from Visual Studio and SQLserver and no, I rather not want to add more systems if possible):
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
You have two questions:
You are using PdfPRow, but you're not supposed to do that. The PdfPRow class is for internal use only. You should work at the PdfPCell level. If you want to color complete rows, you can do so by using a PdfPTableEvent. See for instance the colored rows in alternating.pdf. They were colored in an AlternatingBackground table event.
You have difficulties creating the color #c5c5c5. The hexadecimal value C5 equals 197, hence you want to create the following color object: new BaseColor(197, 197, 197);
Your main mistake is that you create a PdfPRow by adding an array of PdfPCell objects. Where did you get inspiration to do so? If you find somebody who wrote such an example, please let me know and if he's near, I'll personally spank him ;-)
Tables are created like this:
PdfPTable table = new PdfPTable(5);
PdfPCell Quantity = new PdfPCell(new Phrase("Quantity"));
table.AddCell(Quantity);
PdfPCell Title = new PdfPCell(new Phrase("Title"));
table.AddCell(Title);
PdfPCell UniPr = new PdfPCell(new Phrase("Unit Price"));
table.AddCell(UniPr);
PdfPCell Disc = new PdfPCell(new Phrase("Discount"));
table.AddCell(Disc);
PdfPCell Total = new PdfPCell(new Phrase("Total"));
table.AddCell(Total);
There is an even easier way to do this. This easier way also allows you to define the background color for every cell:
PdfPTable table = new PdfPTable(5);
table.DefaultCell.BackgroundColor = new BaseColor(197, 197, 197);
table.AddCell("Quantity");
table.AddCell("Title");
table.AddCell("Unit Price");
table.AddCell("Discount");
table.AddCell("Total");
The AddCell() method will wrap the strings inside a Phrase. Create a PdfPCell with this Phrase and apply all the properties you've defined for the DefaultCell to that cell. This way, you can make sure that all the cell have the same back ground color (or border, or...). Obviously, the properties of the DefaultCell will be ignored if you create PdfPCell instances yourself.

Read Last line from First column using Aspose.Words v13.1.0

I have a word document with two column layout.
How to read last line from first column and read first line from second column in a word document.If first column last line text is in specific format, then move one line down which would automaticaly moves the text to next column(second).
Please let me know how to achieve this in .net using Aspose.Words V13.1.0
First you need to download offline samples pack from this link to use the following code example. Then extract the archive and from the DocumentLayoutHelper example, include the RenderedDocument and LayoutEntities source files in to his application.
Here is the sample code:
Document doc = new Document(dataDir + "Test.docx");
// This sample introduces the RenderedDocument class and other related classes which provide an API wrapper for
// the LayoutEnumerator. This allows you to access the layout entities of a document using a DOM style API.
// Create a new RenderedDocument class from a Document object.
RenderedDocument layoutDoc = new RenderedDocument(doc);
// Loop through the layout info of each page
foreach (RenderedPage page in layoutDoc.Pages)
{
if (page.Columns.Count > 1)
{
// Find the last line in the first column on the page.
RenderedLine lastLine = page.Columns.First.Lines.Last;
// This is the pargraph which belongs to the last line on the page, implement required logic and checks here.
Paragraph para = lastLine.Paragraph;
if (para.ParagraphFormat.StyleIdentifier == StyleIdentifier.Heading1)
{
// Insert a blank paragraph before the last paragraph in the column.
para.ParentNode.InsertBefore(new Paragraph(doc), para);
}
// This is how to get the first line in the second column and the related paragraph.
// Use this if it is required.
RenderedLine secondColumnLine = page.Columns[1].Lines.First;
Paragraph secondColumnPara = lastLine.Paragraph;
}
}
PS, Hope that above example can fulfil your requirements. My name is Nayyer and I am Support/Engangelist developer at Aspose.

Excel file unreadable after adding a "SUMIF" function to a sheet with C# .NET

When I try to add a SUMIF formula to an Excel file that has data, Excel says the file has "unreadable content" and asks if it has to try to recover the contents of the file. If I then click "Yes", it removes said formula and opens the file.
When I try to copy-paste the same SUMIF formula that was generated in the Excel file manually, it works. When I try another formula (a simple "SUM" for instance) it works.
Does anyone have any idea what could be wrong?
I'm using the OpenXML SDK from Microsoft to write to the Excel file. Again, this code works perfectly for some formulas (e.g. SUM), but not for SUMIF.
/// <summary>
/// Gets or set the cell formula
/// </summary>
public string Formula
{
get
{
return _cell.CellFormula.Text;
}
set
{
if(_cell.CellFormula == null)
_cell.CellFormula = new CellFormula();
_cell.CellFormula.Text = value;
}
}
Edit: After opening the Excel file and checking the xml files within, I found that the SUMIF function is saved in the exact same way as the SUM function ("=SUMIF(J3:J33;L34;N3:N33)" and "=SUM(N3:N33)" respectively, both without quotes), so there is no real difference in how the formula is written to the file.
Thanks in advance!
-- Spoiler: The solution is to use "," instead of ";" when working with formulas in your code.
Whenever I get unreadable content errors when working with the Open XML SDK, I will create a blank worksheet and add the piece that is causing the errors to that worksheet. I will then use the Open XML SDK 2.0 Productivity Tool to see what gets generated behind the scenes and use the code it produces to get rid of the unreadable content errors.
I did those steps and noticed the following were added when you add the SUMIF formula. The first being you need to add the formula to the cell using the following code:
// Creates an Cell instance and adds its children.
public Cell GenerateCell()
{
Cell cell1 = new Cell(){ CellReference = "A1" };
CellFormula cellFormula1 = new CellFormula();
cellFormula1.Text = "SUMIF(J3:J33,L34,N3:N33)";
CellValue cellValue1 = new CellValue();
cellValue1.Text = "0";
cell1.Append(cellFormula1);
cell1.Append(cellValue1);
return cell1;
}
This will produce the following XML:
<x:c r="A1" xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<x:f>SUMIF(J3:J33,L34,N3:N33)</x:f>
<x:v>0</x:v>
</x:c>
The text value is just the result of the summation, which is zero in my case since the range I defined were empty.
Next you need to make sure the worksheet contains a sheetDimension which is defined as:
This element specifies the used range of the worksheet. It specifies
the row and column bounds of used cells in the worksheet. This is
optional and is not required. Used cells include cells with formulas,
text content, and cell formatting. When an entire column is formatted,
only the first cell in that column is considered used.
The code that code generated for me was:
// Creates an SheetDimension instance and adds its children.
public SheetDimension GenerateSheetDimension()
{
SheetDimension sheetDimension1 = new SheetDimension(){ Reference = "A1" };
return sheetDimension1;
}
The XML looks like:
<x:dimension ref="A1" xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main" />
Next you need to make sure the worksheetPart contains a calcChainPart which will have a calcChain element with a calculationCell child.
This element represents a single cell, which shall contain a formula,
in the calc chain. Cells are calculated in the same order as the c
elements appear in the Calculation Chain part.
This just tells excel which sheet contains the formula and which cell it is applied to. Here is the code and XML for mine:
// Creates an CalculationCell instance and adds its children.
public CalculationCell GenerateCalculationCell()
{
CalculationCell calculationCell1 = new CalculationCell(){ CellReference = "A1", SheetId = 1 };
return calculationCell1;
}
<x:c r="A1" i="1" xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main" />
Finally, the workbookPart needs a calculationProperties element which defines the collection of properties the application uses to record calculation status and details. Calculation is the process of computing formulas and then displaying the results as values in the cells that contain the formulas.
// Creates an CalculationProperties instance and adds its children.
public CalculationProperties GenerateCalculationProperties()
{
CalculationProperties calculationProperties1 = new CalculationProperties(){ CalculationId = (UInt32Value)125725U };
return calculationProperties1;
}
<x:calcPr calcId="125725" xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main" />
As you can see, all of these various elements and parts are created for you behind the scenes when you add a formula to a cell when using Excel. Unfortunately, you are responsible for adding the necessary elements when adding formulas using the Open XML SDK. Most likely one of these elements are missing from your Excel document, which is why you are probably getting an unreadable content error when opening up your Excel document.

Categories

Resources