Spire.Doc is a professional Word .NET library specifically designed for developers to create, read, write, convert and print Word document files. Get free and professional technical support for Spire.Doc for .NET, Java, Android, C++, Python.

Mon Aug 22, 2011 7:24 pm

I have special needs that willnot be met by the standard way of doing word automation, I have to inject html code into my word document (not as html, but converted to the equivalent word formatted text). My user is entering text using a jquery component to allow formatting. Once he is done, he will click submit...this text will then be injected into a template, using the usual means for this.
1) However i have a limitation, the html is coming in as html, and needs to be inserted as word formatted text, I have seen in the past an example that would allow to push into a Paragraph.AppendHtml, my value....does this convert it into word formatted equivalent....?

2) I need to push values into tags/markers such as {{TAG}}, which is not a true bookmark per se, as well, does not follow regular <tag> convention for automation, this is because we have db mapping for each tag to our web form components, which is why we need to use {{ instead of < (as < is used by html)
This being a limitation, I was wondering about cycling through each word on a page in my document.... as my previous work used the word interop dll, and had a property called .Range that I could call, for each range in document... is there an equivalent property I can use to cycle through the words in the document in spire.doc dll?

Thanks all for your help in advance, I would really greatly appreciate any help as this is due very quickly to demo the usage of spire to my company, and being new, I want to impress upon them the quick and efficient server side automation we can do, of course my knowledge being a limitation right now.

Thanks guys

hesaigo999ca
 
Posts: 18
Joined: Thu Aug 18, 2011 6:07 pm

Mon Aug 22, 2011 7:31 pm

It must be april fools...I just read the doc.

There is no explanation, or samle text, not even a small description as to what will happen when you call a function.
Needs MAJOR documentation input. I dont know if I use the AppendHtml function, if it will append to html, or it will convert text to html, or if it will take html text and convert it to word text....not really clear!!!

hesaigo999ca
 
Posts: 18
Joined: Thu Aug 18, 2011 6:07 pm

Mon Aug 22, 2011 8:30 pm

Ok, so i found this amongst the examples, and twesaked it a bit using regex...
System.Text.RegularExpressions.Regex regx = new System.Text.RegularExpressions.Regex(@"\{\{[^{}]+\}\}");
Spire.Doc.Documents.TextSelection[] textSelections = document.FindAllPattern(regx);
foreach textselection{
...do stuff
}

this retursn me a collection of my tag markers, what I need to know now is how to inject the html code so that it is not html inside word, but converts to word formatted text...instead of <stuff>....etc...

Unless of course it is not possible to replace the text returned from this textselection...but i will keep trying to get this working....

hesaigo999ca
 
Posts: 18
Joined: Thu Aug 18, 2011 6:07 pm

Mon Aug 22, 2011 8:36 pm

ok so the following works now...
foreach (Spire.Doc.Documents.TextSelection selection in textSelections)
{
selection.GetAsOneRange().Text = "new text";
}
i can set the text, however, i do not see the following...
AppendHtml(htmltext); as a possible input method...which leads me to believe that this will only be inserted as regular text then...
can someone please let me know if there is a way to insert html so that it does not view as html, but as nicely fomratted word text that mimics the html formatting....

thanks

hesaigo999ca
 
Posts: 18
Joined: Thu Aug 18, 2011 6:07 pm

Tue Aug 23, 2011 10:31 am

Dear Leon Anderson,

The demo MergeHTML attached just showed you how to inject your data formatted by html ( with html tags ) into a word template which has many pre-laid tags such as {{TAG}}. During that process, the html was converted inside the injection into word formatted text (word syntax).
Harry
Technical Support / Developer,
e-iceblue Support Team
User avatar

harry.support
 
Posts: 180
Joined: Mon Nov 08, 2010 3:11 pm

Tue Aug 23, 2011 1:05 pm

Hi there, thanks for your prompt reply, the only question is that the previous MergeHtml project had used the Paragraph.AppendHtml() function, which I am not sure if when I assign text inside the code below, it will convert it /understand it as word text, or will display as html text....I think the appendhtml function does the conversion....
foreach (Spire.Doc.Documents.TextSelection selection in textSelections)
{
selection.GetAsOneRange().Text = "new text";
}

I am not able to use regular bookmarks, we can only use {{TAG}} to specify text replacement, therefor can not use the MergeHtml example per seh, however, i am able to get back all tags with the regex find, and then i could use a way indirectly to inject the text....say maybe like a fake out....
Paragraph pr = new Paragraph()
pr.AppendHtml(htmltexthere);
selection.GetAsOneRange().Text = pr.Text;

sort of thing...could this be done maybe???

thanks in advance, almost finished with this demo project, cant wait to show the boss how great your software is!!!

hesaigo999ca
 
Posts: 18
Joined: Thu Aug 18, 2011 6:07 pm

Tue Aug 23, 2011 2:30 pm

I think I may have something working, not sure though, need more testing...
I declare an empty document, create a new paragraph, use the appendhtml function, then use the paragraph.text property to get back the proper word formatted text, I am unceratin how to apply the paragraph contents though....

Spire.Doc.Documents.TextSelection[] textSelections = document.FindAllPattern(regx);//.FindAllString(this.textBox1.Text, true, true);
foreach (Spire.Doc.Documents.TextSelection selection in textSelections)
{
Spire.Doc.Document document2 = new Spire.Doc.Document();
Spire.Doc.Documents.Paragraph pr = document2.CreateParagraph();
pr.AppendHTML("user input in html format");
selection.GetAsOneRange().Text = pr.Text; <- dont know if this will set the text from the paragraph as it is showing in this paragraph, or will it
lose the formatting, and only apply the actual text, and not the text formatting???
}

hesaigo999ca
 
Posts: 18
Joined: Thu Aug 18, 2011 6:07 pm

Tue Aug 23, 2011 2:34 pm

I get an error here
Spire.Doc.Documents.Paragraph pr = document2.CreateParagraph();
pr.Text = "hithere";
pr.AppendHTML("<i><b><h2>hello world</h2></B></i>"); <- ....error Object reference not set to instance of object....???

hesaigo999ca
 
Posts: 18
Joined: Thu Aug 18, 2011 6:07 pm

Tue Aug 23, 2011 2:50 pm

I came across something from google, but downloads are corrupted, maybe someone can review and see if these are still good examples...?
http://www.e-iceblue.com/Knowledgebase/ ... =component

hesaigo999ca
 
Posts: 18
Joined: Thu Aug 18, 2011 6:07 pm

Wed Aug 24, 2011 6:12 am

hesaigo999ca wrote:I get an error here
Spire.Doc.Documents.Paragraph pr = document2.CreateParagraph();
pr.Text = "hithere";
pr.AppendHTML("<i><b><h2>hello world</h2></B></i>"); <- ....error Object reference not set to instance of object....???

You must add your paragraph to a section, please try:
Code: Select all
Section section = doc.Sections[0];//or doc.AddSection();

Spire.Doc.Documents.Paragraph pr = section.AddParagraph();

pr.Text = "hithere";

pr.AppendHTML("<i><b><h2>hello world</h2></B></i>");

Because function AppendHTML maybe generate multiple paragraphs, for example: pr.AppendHTML("<p>p1</p><p>p2</p><p>p3</p><p>p4</p>");
Harry
Technical Support / Developer,
e-iceblue Support Team
User avatar

harry.support
 
Posts: 180
Joined: Mon Nov 08, 2010 3:11 pm

Wed Aug 24, 2011 6:15 am

hesaigo999ca wrote:I came across something from google, but downloads are corrupted, maybe someone can review and see if these are still good examples...?
http://www.e-iceblue.com/Knowledgebase/ ... =component

The correct url is http://www.e-iceblue.com/Knowledgebase/ ... -HTML.html
Harry
Technical Support / Developer,
e-iceblue Support Team
User avatar

harry.support
 
Posts: 180
Joined: Mon Nov 08, 2010 3:11 pm

Wed Aug 24, 2011 6:32 am

If your new text is plain text without html tags, you could use
Code: Select all
selection.GetAsOneRange().Text = "new text";

but if it includes html tags, you could not use
Code: Select all
selection.GetAsOneRange().Text = "<p>p1</p><p>p2</p><p>p3</p><p>p4</p>";

you must call AppendHTML method to convert your new text ( with html tags ) to word text (with word style).
The code
Code: Select all
selection.GetAsOneRange().Text = pr.Text;

just copy the plain text, it will lose the text style.
So we suggest you use our code in the demo MergeHTML.zip in my previous post.
Code: Select all
using System;
using System.Collections.Generic;
using System.Text;

using Spire.Doc;
using Spire.Doc.Documents;
using Spire.Doc.Fields;
using Spire.Doc.Interface;

namespace MergeHTML
{
    class Program
    {
        static void Main(string[] args)
        {
            Document doc = new Document(@"..\..\InvoiceTemplate2.doc");
            System.Text.RegularExpressions.Regex regx
                = new System.Text.RegularExpressions.Regex(@"\{\{[^{}]+\}\}");
            Spire.Doc.Documents.TextSelection[] textSelections = doc.FindAllPattern(regx);           

            Dictionary<String, String> data = GetUserEnteringData();

            foreach (TextSelection selection in textSelections)
            {
                TextRange range = selection.GetAsOneRange();
                Paragraph p = range.OwnerParagraph;
                int index = p.Items.IndexOf(range);

                String key = selection.SelectedText;
                key = key.Substring(2, key.Length - 4);
                String value = null;
                if (data.TryGetValue(key, out value))
                {
                    int count1 = p.Items.Count;
                    int newContentIndex = index + 1;

                    //append data with html tags
                    p.AppendHTML(value);
                    int count2 = p.Items.Count;

                    //move
                    for (int i = 0, count = count2 - count1, lastItemIndex = count2 - 1; i < count; i++)
                    {
                        ParagraphBase item = p.Items[lastItemIndex];
                        p.Items.RemoveAt(lastItemIndex);
                        p.Items.Insert(newContentIndex, item);
                    }
                }

                //remove tag
                p.Items.RemoveAt(index);
            }

            doc.SaveToFile("test.doc");
            System.Diagnostics.Process.Start("test.doc");
        }

        private static Dictionary<String, String> GetUserEnteringData()
        {
            Dictionary<String, String> data = new Dictionary<String, String>();
            data["OrderID"] = "<span style=\"font-size: 10pt; font-family: Arial\"><b><font color=\"red\">E7B0</font>-<font color=\"orange\">10726</font></b></span>";
            data["ShipName"] = "<span style=\"font-size: 10pt; font-family: Arial\">Eastern Connection</span>";
            data["ShipAddress"] = "<span style=\"font-size: 10pt; font-family: Arial\">35 King George</span>";
            data["ShipCityRegionPostalCode"] = "<span style=\"font-size: 10pt; font-family: Arial\">London  WX3 6FW</span>";
            data["ShipCountry"] = "<span style=\"font-size: 10pt; font-family: Arial\">UK</span>";
            data["CompanyName"] = "<span style=\"font-size: 10pt; font-family: Arial\">Eastern Connection</span>";
            data["Address"] = "<span style=\"font-size: 10pt; font-family: Arial\">35 King George</span>";
            data["CityRegionPostalCode"] = "<span style=\"font-size: 10pt; font-family: Arial\">London   WX3 6FW</span>";
            data["Country"] = "<span style=\"font-size: 10pt; font-family: Arial\">UK</span>";
            data["CustomerID"] = "<span style=\"font-size: 10pt; font-family: Arial\">EASTC</span>";
            data["Salesperson"] = "<span style=\"font-size: 10pt; font-family: Arial\">Margaret Peacock</span>";
            data["OrderDate"] = "<span style=\"font-size: 10pt; font-family: Arial\">1997-11-03</span>";
            data["RequiredDate"] = "<span style=\"font-size: 10pt; font-family: Arial\">1997-11-17</span>";
            data["ShippedDate"] = "<span style=\"font-size: 10pt; font-family: Arial\">1997-12-05</span>";
            data["ShippersCompanyName"] = "<span style=\"font-size: 10pt; font-family: Arial\">Speedy Express</span>";
            data["InvoiceSubtotal"] = "<span style=\"font-size: 10pt; font-family: Arial\">655.00</span>";
            data["Freight"] = "<span style=\"font-size: 10pt; font-family: Arial\">16.56</span>";
            data["InvoiceTotal"] = "<span style=\"font-size: 10pt; font-family: Arial\">671.56</span>";
            return data;
        }
    }
}

Harry
Technical Support / Developer,
e-iceblue Support Team
User avatar

harry.support
 
Posts: 180
Joined: Mon Nov 08, 2010 3:11 pm

Wed Aug 24, 2011 2:10 pm

I am thankful for the help, and I got this code to work....just to let you know though...the orignal code had no mention of textranges, which is why i could not use it....the new code you sent did work, thanks for that.

Here is the original code from the example...
foreach (KeyValuePair<String, String> data in GetData())
{
Bookmark bookmark = doc.Bookmarks[data.Key];
if(bookmark != null)
{
BookmarkEnd be = bookmark.BookmarkEnd;
Paragraph p = be.OwnerParagraph;
int index = p.Items.IndexOf(be);
int count1 = p.Items.Count;

//append data with html tags
p.AppendHTML(data.Value);
int count2 = p.Items.Count;

//move
for(int i = 0, count = count2 - count1, lastItemIndex = count2 - 1; i < count; i++)
{
ParagraphBase item = p.Items[lastItemIndex];
p.Items.RemoveAt(lastItemIndex);
p.Items.Insert(index, item);
}
}
}

Here is the new code...
foreach (TextSelection selection in textSelections)
{
TextRange range = selection.GetAsOneRange();
Paragraph p = range.OwnerParagraph;
int index = p.Items.IndexOf(range);

String key = selection.SelectedText;
key = key.Substring(2, key.Length - 4);
String value = null;
if (data.TryGetValue(key, out value))
{
int count1 = p.Items.Count;
int newContentIndex = index + 1;

//append data with html tags
p.AppendHTML(value);
int count2 = p.Items.Count;

//move
for (int i = 0, count = count2 - count1, lastItemIndex = count2 - 1; i < count; i++)
{
ParagraphBase item = p.Items[lastItemIndex];
p.Items.RemoveAt(lastItemIndex);
p.Items.Insert(newContentIndex, item);
}
}

//remove tag
p.Items.RemoveAt(index);
}

I got it to work....I am now having an issue though, as the AppendHtml function seems to be validating against http://www.w3.org/1999/xhtml
and giving me this error
"The element 'i' in namespace 'http://www.w3.org/1999/xhtml' has invalid child element 'h2' in namespace 'http://www.w3.org/1999/xhtml'. List of possible elements expected: 'http://www.w3.org/1999/xhtml:a http://www.w3.org/1999/xhtml:br http://www.w3.org/19...

I have a <H2> tag inside a <I> tag...which I guess is not xhtml complient, but then again, there are may things that are not...is there any way I could maybe force this validation to bypass errors of this nature, or am I stuck with being complient, and need to redo the html code being injected into the document?

Thanks again for all the great help, almost there...just need this one question answered.

hesaigo999ca
 
Posts: 18
Joined: Thu Aug 18, 2011 6:07 pm

Thu Aug 25, 2011 10:09 am

Could you please post the html code which has the error. We will try to reproduce your problem and give you some suggestion.
Harry
Technical Support / Developer,
e-iceblue Support Team
User avatar

harry.support
 
Posts: 180
Joined: Mon Nov 08, 2010 3:11 pm

Thu Aug 25, 2011 2:04 pm

the code was simple enough...

AppendHtml("<b><h2>hi there</h2></b>");
gave me an error about xhtml complience....I guess the h2 tag does not belong inside a b tag???

If this is the type of error i can expect, that means user input will have to be tested to be xhtml complient (as it is coming in from the ckeditor)
before being passed into this function, as I can not have any problems to delay my input from the user.

Thanks for all your help guys...

hesaigo999ca
 
Posts: 18
Joined: Thu Aug 18, 2011 6:07 pm

Return to Spire.Doc