How to dynamically populate RTF documents? - c#

Is it possible to create an RTF template document and programmatically insert elements like tables or populate variables? If so, what do I need to do this?
I understand that there is a RichTextBox control that can represent the document, but I need to define a template (or more specifically, the sales guys will be defining the template and giving it to me) which I need to then populate with the data. The RichTextBox control is no good to them. We need RTF because not all clients have Word.

As #ToastyMallows suggested, it's come down to a dirty game of replacing strings.
I'm using the following to generate tables and formatting and stuff:
http://www.codeproject.com/Articles/30902/RichText-Builder-StringBuilder-for-RTF

I've done this, but in an old Windows Forms client-side application using Word automation. It works but not elegantly. We defined the templates in WordPad I think, then extracted the RTF which gets stored in a database. There are pre-defined fields that get populated on document creation.
One thing I have discovered in doing RTF stuff, is that the meaning of RichText (the format) and RichText (as in controls) are not necessarily the same.

Related

Generating Word Documents with content contorls

I have an word document template that only changes in several fields.
I remember looking around using google-fu and found that you can bind an xml to content controls and dynamically generate word documents through that method.
Unfortunately it's been a while since I revisited this particular problem, and all I remember about this problem was that it was unnessarily clunky and hard to manage.
Are there any opensource solutions that are more elegant? Or a better way to go at this?
I think it is fair to describe content control XML data binding as the latest in a series of techniques which enable Word document generation/automation.
Content control data binding was introduced in Word 2007, so is now not all that new. When you do document automation, you generally also want support for:
conditional inclusion/exclusion of content
repeating data (eg table rows, list items)
There are ways to do both of the above with content controls, and Microsoft has recently released dedicated support for repeating data.
Content control data binding is less brittle than older approaches, but if you don't like XML and XPath, you might not call it elegant :-)
The legacy approaches "baked-in" to Word include:
fields: MERGEFIELD, form fields, or custom fields
use of bookmarks
A problem with these is that it is easy for the author user to mistakenly delete them. Another problem is that they aren't as easy for a developer to work with at the XML level (though maybe OK via VBA or VSTO).
The other approach is to include magic text strings on the document surface, and there are various tools around which do this. This has an initial appeal, but the problem with this is that what looks like a contiguous text string on the document surface can be split up at the XML level, because of:
spelling/grammar correction
rsid (edits made at different times or by different people)
formatting (eg font size, appearance changes)
In short, yeah, there are alternatives. Choose your poison.

How to generate an RTF document server side in c#

I have tried using the System.Windows.Documents.FlowDocument server side, but ran into a problem with images.
What I need to produce is a document with headings, section breaks, page breaks, images (with text wrapping around from the left or the right), tables and ideally some kind of table of contents.
I use c# and asp.net.
Is there a library that will do most of this?
RTF has been chosen because the document needs to be openable in older versions of word, be editable, and we can't run word on the server.
Thank-you
I used MigraDoc in the past, it is a free library. You can create PDFs or RTFs. Just Google it.
I have started using .net rtf writer.
It produces clean rtf, but doesn't do everything I need.
There is pretty good documentation for rtf here.
I am working some things out for my self. For example, I needed to be able to wrap text around an image. Whilst the rtf writer above enables you to add images to documents, it does so by putting the image in its own paragraph. What I need is a shape element.
In the rtf it ends up looking something like this (some of the numbers define the size and position of the image in twips):
{\shp{\*\shpinst\shpleft3801\shptop1\shpright8300\shpbottom4500\shpfhdr0\shpbxcolumn\shpbxignore\shpbypara\shpbyignore\shpwr2\shpwrk0\shpfblwtxt0\shpz0
{\sp
{\sn pib}
{\sv
{\pict\pngblip\pichgoal4499\picwgoal4499
-- image binary data goes here --
}}}
{\sp
{\sn fLine}
{\sv 0}}}}
I sometimes just save something in word and try and understand what it did (but word seems to add a lot of noise).

Generate PDF based on a Word document for each data item

There're a data list with hundreds of data items (suppose each item is a customer), and a predefined word document as template, the requirement is - for each data item, fill corresponding data into template fields, and generate a readonly PDF file as result.
Prefered platform is ASP.NET with C#.
I found two solutions:
Change the word document into a PDF form, and use iTextSharp to fill the form fields. But create the PDF form with correct format (font, layout, etc.) is a difficult work, and it needs particular tool and new skill when system user wants to add new template (unless the PDF form is always created by developer).
Add text placeholder in the word file, and the program can read word file, replace text, and convert into PDF. But I'm not sure which components should be used.
I'd like to get some advices on this problem. tks.
Update 20130416:
After some searching & experiments, my conclusion is below:
Client solution: use Microsoft.Office.Interop.Word (Office2007+plugin or Office2012) to read data, convert to pdf, etc. But this method running on server side may be unsafe.
Server solution:
Make PDF form, and use iTextSharp to fill the form fields. The disadvantage has been mentioned above.
Make HTML template, and replace field placeholders, and use iTextSharp+XMLWorker to convert HTML to PDF. The difficulty is create the HTML template manually and optimize the PDF effect.
MS SharePoint Office Automation Service is a server solution based on MS Office, perhaps this method will be easier, but it needs license and SharePoint server cost.
Finally, I chose the HTML template solution for this request. QED.
Another option would be to use Tx Text Control for ASP.NET. They have a
mailmerge feature that allows you to fill data into a word template.
The merged document can easily be saved as a pdf.
For the second option you can use iTextsharp or Aspose which supports the placeholder replacement and generation PDF, it supports creating files based on templates of MSWord and Openoffice which could be usefull for user who do not want to buy MSWord only to create a template.
Another option, you can use nustache templates, fill them with list data and then use xmlworker from ItextSharp to render to pdf.

Update Chart Data while creating Dynamic Word Documents

We have a requirement, in which we need to create dynamic word document and these word documents contains Table, Chart, text and images to be replace/update dynamically. So we decided to create a template and place text holders at dynamic places. To create new document by reading and updating Template we decided to go for OpenXML SDK 2.0.
I am successfully able to replace/update Text/Table and Image content (for place holder tagging we are using Content Controls and we assign a unique tag to each content control.)
I am still trying to figure out, how we will modify the chart data. As far as i know about chart part, it has its own underlying xlx data file, in which it stores the data. So now to update chart part i can think of three different solutions.
1.) Update underlying xlx file by using Open SDK. I am not sure if this can be done or not, but considering its just an xlx file, so i should be able to modify it using Open XML Sdk itself.
2.) Create a chart, convert into image and then replace the image.
3.) I have also read about Custom XML, in which we can bind Content Controls with that XML. So the idea is to create a chart with Custom XML as datasource and then update data xml dynamically.
Any suggestions or Code samples would be appreciated. I am using Open XML SDK 2.0.
I tried with approach1, I modified the underlying xlsx data, but seems it was not sufficient as under Chart.xml -> ChartSpace -> Chart-> PlotArea -> BarChart -> BarChartSeries -> Values, it was saving those numeric values. So i guess i am missing a component, which can read from xlsx and then updates chart accordingly. For now i have manually updated the both xlsx and Values so that it is reflected properly.

XPS form filling

Is there a way to do form filling with XPS documents in C#?
It wouldn't be an ideal solution. The reason is that text in XPS is represented by Glyphs, in which characters (roughly speaking) are specified as indexes into a particular typeface's table of character shapes, rather than in something handy like Unicode. And the Glyphs have to be specifically positioned, each character offset from the string origin. If a string has to wrap onto multiple lines, that has to be done by putting in many separate Glyphs objects, all individually positioned. It's not a logical format, but a physical one, and it isn't particularly amenable to being altered after it's generated.
You'd be much better off defining the template document as a FlowDocument. That's a much more logically manipulable format, rather than a physical "frozen" format. (An XPS document is technically a FixedDocument). You can then freeze a FlowDocument into a FixedDocument to export it as XPS, when it has been filled in.
Read more about Flow Documents.
Here's how you do it.
First, you create an object (POCO is fine) that contains the form fields you wish to have the user fill in for your form. Next, you create your form as a FixedDocument. It should have Bindings that work against your POCO. Then you create a Window that is set up so that the user can enter values for those fields.
Bind the POCO (plain old CLR object) to the TextBoxes in the Window. After the user has entered the form data, take your now filled-in object and set it as the DataContext of the FixedDocument. Create an XpsWriter and Write your FixedDocument to your output (file, printer, etc).
I'd give you code, but since I'm actually doing this (or something relatively similar) for work I don't think I can. I can tell you that the hardest part is dealing with the XPS document. You can judge relative to your experiences there.
If you want to fill a XPS form, yes. XPS is XML, so you can change it.
Modifying XPS is certainly possible, it depends a bit on how you want this to work and the amount of programming you are willing to do (but this might be true for every programming issue ;-)).
Anyway: feel free to e-mail me directly on info-at-nixps-dot-com.
I never found a really great solution, so I made one. Check out www.flexsoftinc.com to see my program XPS Express.

Categories

Resources