I want a way to manipulate a word document.
The document is a word template .DOTX file, and I need to hide and/or show specific paragraphs of the document based on conditions on my ASP.NET/C# application.
For example, if i entered the first and last names in my form, the generated word doc will show both fields, else of the last name is not entered it will not be shown in the generated document. I already know how to generate the doc but I dont know how to hide and/or show specific elements.
I am using Docentric Toolkit for this kind of scenario. The toolkit itself is using OpenXML in the background, so no Word installation is necessary. I suggest you take a look at the example for conditional content here.
In your ASP.NET application you prepare a data model. This model should also include a boolean field where you set true/false value depending on whether you want to show conditional content in the document or not. The document template contains conditional tag, which is used as a placeholder for conditional content. Other tags (placeholders) can be nested in conditional content.
Related
I need to get a text that's being written by a user (in CKEditor HTML), and then add that text to a MigraDoc document, as a paragraph or whatever I need it to be.
My idea was converting the text to an MDDDL document (in memory) and add it to the document. But I don't know if there are any DLLs that permit that behaviour.
So, my question is, can someone give me pointers or advice on how I could make this happen? Should I parse the HMTL text? If so, to what should I parse it? How can I add it afterwards?
Neither PDFsharp nor MigraDoc can parse HTML, so either write your own code or try to find a third-party library (which may not exist yet).
I would probably convert the HTML directly to MigraDoc document objects in memory.
MigraDoc / PDFSharp can't do this.
But, you could use HtmlAgilityPack nuget and then use its htmlDoc.DocumentNode.Descendants() to pull out the pieces of text from html in a flat list kind of a structure, and node.ParentNode.Name to figure out the tag that the text is wrapped in. And then insert the text into your MigraDoc document with something like .AddFormattedText() and apply custom MigraDoc styles to it - i.e. if the parent tag is "strong" then apply a MigraDoc style where Font.Italic = true; etc..
In MigraDoc, I know I can add a page count reference to the document using AddNumPagesField, but is it possible to determine if there are multiple pages?
The methods AddPageField and AddNumPagesField do not contain any useful information.
Basically, I want to do something like:
if(/* document has multiple pages*/) {
//do something here
}
With MigraDoc, pages do not exist until a document is rendered.
MigraDoc does not create any pages when rendering to an RTF file. Pages do not exist there.
MigraDoc creates pages when rendering to PDF.
AddPageField and AddNumPagesField are placeholders. They remain placeholders when rendering to RTF, they will be replaced by the real values when creating PDF - their values cannot be determined while the MigraDoc document is still being created.
What you can do: Assume the most likely case (e.g. multiple pages) and create the document. If it only has a single page, then discard it and create it again for the single-page case.
Or maybe use PDFsharp to modify the PDF file created by MigraDoc as needed, now adding the contents that depend on the page count.
What I would like to do is to be able to write some hidden marks in the document, so that when the user fills in some information, then I can process each part of the document according to the marks or sections that surrounded it. I'm using .NET, any ideas? Thanks
Take a look at SdtElements tag, OpenXml Sdk and Word 2007 Content Control Toolkit
The essence is:
Create a Word document that will be your template
In Word, turn on Developer tab
In the Developer tab there is a Controls group. Click the "Aa" ones to insert a new content tag, click "Properties" to edit the tag alias and data, turn on Design Mode to see the content tags
The steps below apply if your app can output an XML you would bind to your document:
Open the Word Content Control Toolkit
Open the document you created
Attach an xml in the right-side panel
double-click on content tags to edit their XPath binding or use drag-drop; see WCCT manual for that
Once you have your template prepared, depending on your actual task at hand you can do many things with these content tags, including:
replace the custom xml part in your document to update the data users will see when they open it
use openxml sdk to replace the data without opening it in Word
use the template to collect data (possible but unreliable, not recommended)
delete and insert content tags from code via openxml sdk
In your code you can find the content tags by using LINQ queries over OpenXmlSdk objects like so:
var contentTags = document.MainDocumentPart.Document.Body
.Descendants<SdtElement>()
.Where(x => x.SdtProperties.GetFirstChild<Tag>() != null && x.SdtProperties.GetFirstChild<DataBinding>() != null)
.Select(x => x.SdtProperties.GetFirstChild<Tag>().Val.InnerText =="Whatever Tag you're looking for or other condition to match several")
.ToList();
You can use custom document properties as described here or here
I have retrieved a string of XML which contains the content of a single rich text content control using the property contentControl.Range.WordOpenXml in VSTO (C#).
This contains a number of <pkg:part> tags enclosed within a <pkg:package> tag depending on the content within the content control. If there are images in the content, they are contained inline as a byte array in a different <pkg:part> tag.
How do I use this XML to copy the contents of this rich text control to a content control in a different word document.
PS : I am using Open Xml SDK 2.0, C# and Word 2010
Documents and Ranges have a WordOpenXML property, as you have discovered. Ranges, however, also have an InsertXML method which will take a WordOpenXML string, e.g.:
var wordOpenXML = contentControl.Range.WordOpenXml;
document.Range().InsertXML(wordOpenXML);
This will result in the contents of the Content Control being inserted into document. You can use a more specific Range to determine exactly where the content gets copied to in your document. It will also work within the same document, of course.
I would like to know if there is a way to "play" with sentences in a .docx.
Here's what I need to do:
I have a paragraph in a document
exemple of my paragraph:
This is a paragraph that I need to format based on some conditions and I can't figure how to do this with openxml sdk.
end of exemple.
So based on a condition that I evaluate in c# I would like to add/remove the text. Another thing that you should know id that I would like the product owner to change the text of the document.
Basicly what I want to acheive is having a template document that my product owner can edit at will but in this document the text might change based on for whom the document is produce.
Thanks
You can create a template document in Word and create a content control in each place you want the text to be dynamically inserted. For each created content control, you should set unique Tag property value.
In your c# application code, you can then find a content control by its tag quite easily. After you find it, you can save its parent node, remove the content control and insert the text you want as a child paragraph element for the parent node saved earlier.
You can add content controls by using Developer tab. If you can't see it, you can use steps described here in order to show it: http://msdn.microsoft.com/en-us/library/bb608625.aspx .
There are some complexities involved in replacing text because text can be broken into multiple runs. If you want your owner to be able to edit the document, this is a problem you must solve. Luckily, there is sample code that you can use as part of the PowerTools for Open XML. PowerTools were written as cmdlets for PowerShell, but you can take the core C# code for your own programs. The TextReplacer.cs module should give you a good starting point. You will need some of the other modules that it depends on, like PtOpenXmlDocument.cs, PtOpenXmlUtil.cs and PtUtil.cs. I hope that helps.