SharpDocx
SharpDocx copied to clipboard
Discussion: Is Adding Formatting Options Useful?
We have been using this project for several years with great success and very few issues (kudos @egonl !) and have recently made some updates to our implementation to expose methods for formatting text in our documents programatically (as opposed to using embedded <%if()..%>
statements in the document templates themselves). This gives us finer control over conditional formatting and cleaner docx templates.
We have currently implemented these as specific commands (<% ApplyBoldStyle("My Bold Text"); %>
) but could easily make the method more generic and perhaps expose the available formats via an enum or other list of options
(<% ApplyStyle(SharpDocxStyles.Bold, "My Bold Text"); %>
).
At this point I'm really just gathering input as to if this would be a useful addition to SharpDocx or if it falls outside of what the project is trying to do. If @egonl thinks this is useful, I'll open a PR and add our suggested implementation for review and consideration. Looking forward to input from other users as well.
Here's an example of how we apply a bold style to a parargraph (could also be just at the run level) in our custom class that inherits SharpDocx.DocumentBase
:
protected void ApplyBoldStyle(string content)
{
try
{
// Usage in template docx: <% ApplyBoldStyle("My Bold Text"); %>
// Add a paragraph with a run with some text.
Paragraph p =
new Paragraph(
new Run(
new Text(content) { Space = SpaceProcessingModeValues.Preserve }));
CurrentCodeBlock.Placeholder.GetParent<Paragraph>().Append(p);
// If the paragraph has no ParagraphProperties object, create one.
if (p.Elements<ParagraphProperties>().Count() == 0)
p.PrependChild<ParagraphProperties>(new ParagraphProperties());
// Get the paragraph properties element of the paragraph.
ParagraphProperties pPr = p.Elements<ParagraphProperties>().First();
// Get the Styles part for this document.
StyleDefinitionsPart part = Package.MainDocumentPart.StyleDefinitionsPart;
// If the Styles part does not exist, add it.
if (part == null)
part = AddStylesPartToPackage(Package);
bool hasStyle = part.Styles.Descendants<Style>().Any(x => x.StyleId == "sdBold");
if (!hasStyle)
{
CreateAndAddCharacterStyle(part,
"sdBold",
"Bold Text",
"sdBold");
}
// Get a reference to the run (indexed starting with 0).
Run r = p.Descendants<Run>().ElementAtOrDefault(0);
// If the Run has no RunProperties object, create one.
if (r.Elements<RunProperties>().Count() == 0)
r.PrependChild<RunProperties>(new RunProperties());
// Get a reference to the RunProperties.
RunProperties rPr = r.RunProperties;
// Set the character style of the run.
if (rPr.RunStyle == null)
rPr.RunStyle = new RunStyle();
rPr.RunStyle.Val = "sdBold";
}
catch(Exception ex)
{
// do some logging!
throw;
}
}
Yes please open a PR: I would like to play a little bit with it. Sounds like a good addition. The <% if() %>
construction is indeed quite limited.