This project has moved. For the latest updates, please go here.

Special ReplaceText

Nov 16, 2011 at 4:12 PM

 

Hello again!

 I would like to know how could i replace special characters as "^011" by another special character as "^0113".

This is to fix a problem when inserting text that comes from another windows app, could have some "line feed" that i'd really like to interpret docx as carriage return.

This is related with this link, where you could understand why i need to do this.

http://maguila.com.ar/2009/02/tips-word-1/

(Translate it cause it's in spanish)

 

Thanks in advance.

Regards.

Nov 17, 2011 at 2:20 PM

To simplify,

the problem is,  how to use ReplaceText to replace Line Feeds by Carriage Return (Paragraph ones). 

This doesn´t work:

 // Line Feed               

char lf = (char)10;               

// Carriage Return               

char cr = (char)13;

doc.ReplaceText(lf.ToString(), cr.ToString());

neither this:

doc.ReplaceText(lf.ToString(), cr.ToString() + lf.ToString())

 

Thanks

Developer
Nov 17, 2011 at 5:54 PM

Hi, mafpinedo

Your question is very interesting. But i suppose that it is impossible to replace the #13 symbol. Next I will try to explain it.  When you write "1 #13 2 #13 3" in your document, MS Word creates next document tree: 

<w:p w:rsidRDefault="00A93C87" w:rsidR="00827B55">
 <w:r>
  <w:t>1</w:t>
 </w:r>
</w:p>
<w:p w:rsidRDefault="00A93C87" w:rsidR="00A93C87">
 <w:r>
  <w:t>2</w:t>
 </w:r>
</w:p>
<w:p w:rsidRDefault="00A93C87" w:rsidR="00A93C87">
 <w:r>
  <w:t>3</w:t>
 </w:r>
</w:p>

So docx doesn't contains three #13 symbols explicitly. Instead of it we have three nodes "p". That's why we can not replace #13 for anything. If you need to replace if, you should see at paragraphs, for example union all paragraphs into single. 

Nov 18, 2011 at 7:23 AM

Thank you for your answer DragronFire.

Problem is just the opposite, i meant, replacing #10 => #13, but anyway i understand the complexity of what you mean.

Finally i fixed in a simple way, before adding the whole text with \n chars, i Split('n') and insert each part as new paragraph, then i apply numbered styles just to the first of theses added paragraphs, and to the rest i created some styles equivalents to the numbered ones, but without the numbered! 

So, everything keeps ordered in the document. Otherwise, the indentation of the paragraphs is annoying due to those '\n'

We will see in future if could be implemented something like this

ReplaceByParagraph(string text, P paragrph);

Best regards,

Miguel

Developer
Nov 18, 2011 at 9:15 AM

You implemented an absolutely right solution! I think the method "ReplaceByParagraph" with such functionality is not obviously, becouse you want to split Paragraph into many their. 

But I can:

  1. add a new method into DocX such as "InsertText(..., Boolean splitIntoParagraphs)"
  2. add a new method into Paragraph such as "SplitBy(Char divider)"

What do you think about it? Maybe, you have some better ideas? 

With respect, Evgeniy

p.s. Are you from, if it is not secret?=)

Nov 18, 2011 at 10:00 AM

 

The big problem is really related with the Styles.

I´m gonna give you some doc files trying to explain  you what i really mean.

Suppose in our main app, have a text field with this lines user entered and what to export to a docx.

"El archipiélago del Perfume está formado por las islas de la Cruz y Redonda, se encuentra en el Océano Atlántico, 4000 kilómetros al SW de la Península Ibérica. 


España tiene un MOU con BOLALAND, por el que puede realizar la explotación conjunta de gas natural en el sur de la Isla de la Cruz."

Text contains obviously a line feed.

When generated the file, calling Insert a simple paragraph in the normal way, and applying one style:

private static void WriteParagraphDocX(Novacode.DocX document, string property, int level, bool isHeading)
        {
                Novacode.Paragraph p = document.InsertParagraph(property);
                // Template Styles are:
                // Ttulo1, Ttulo2, ....., Ttulon
                // Texto1, Texto2, ....., Texton

                    p.StyleName = (isHeading ? TEMPLATE_HEADER : TEMPLATE_NORMAL) + level.ToString();
        }

You will get something like this (**** please, download the files and open with word, otherwise Google docs does not manage the indentation as Word does)

https://docs.google.com/open?id=0B1yd7bR8agHINjU1ZWRkZmItMTY3My00MjRjLWFkMGQtY2U3OTg0NGNkNjZi

By other hand, just splitting and insertting each "line" as a paragraph we got a problem, the numbered applies to all paragraphs! User does not want that, want to keep styles as the defined in plain text!

 

private static void WriteParagraphDocX(Novacode.DocX document, string property, int level, bool isHeading)
        {
            string[] _strArr = property.Split('\n');

            bool firstParagraph = true;

            foreach (string _line in _strArr)  
            { 
                Novacode.Paragraph p = document.InsertParagraph(_line);
                // Template Styles are:
                // Ttulo1, Ttulo2, ....., Ttulon
                // Texto1, Texto2, ....., Texton
                .StyleName = (isHeading ? TEMPLATE_HEADER : TEMPLATE_NORMAL) + level.ToString();
            }
        }

 

You'll get

https://docs.google.com/open?id=0B1yd7bR8agHIMzFjY2Y4ZTUtNGVmYS00ODBjLWJiMDEtMTJiYjE0MzFkN2Mx

Finally the solution:

private static void WriteParagraphDocX(Novacode.DocX document, string property, int level, bool isHeading)
        {
            string[] _strArr = property.Split('\n');

            bool firstParagraph = true;

            foreach (string _line in _strArr)  
            { 
                Novacode.Paragraph p = document.InsertParagraph(_line);
                // Template Styles are:
                // Ttulo1, Ttulo2, ....., Ttulon
                // Texto1, Texto2, ....., Texton
                // Textononum1, Textononum2, ....., Textononumn
                if (firstParagraph)
                {
                    firstParagraph = false;
                    p.StyleName = (isHeading ? TEMPLATE_HEADER : TEMPLATE_NORMAL) + level.ToString();
                }
                else
                    p.StyleName = (isHeading ? TEMPLATE_HEADER : TEMPLATE_NORMAL_NOT_NUMBERED) + level.ToString();
            }
        }

Generating....

https://docs.google.com/open?id=0B1yd7bR8agHIZTQ1ZWNjMWItNGIwMy00ZDc1LThlNmMtMzdlMmE3YTQwNDdi

So, i really don't know what to tell you! xD

I think "InsertText(..., Boolean splitIntoParagraphs)" is easy implementable from outside of the API, but the SplitBy(Char divider) could be useful!

What would be really cool is be able to modify paragraph Styles programatically, in global or specific for a single paragraph style.

Do u know something about this?

By the way i´m from Spain, Madrid as may be you notice by the inserted text and docs :D

Kind regards.

Developer
Nov 18, 2011 at 12:00 PM

Do I understand that you need to start the first paragraph with the "(1)" number? What are TEMPLATE_NORMAL and TEMPLATE_NORMAL_NOT_NUMBERED strings? How you imagine the changing paragraph styles, could you tell me more... Maybe we will think of something interesting =) 

Yes, I have seen it =) I'm from Russia and now I'm studying English seriously, so I will be glad if you show mistakes in my posts =) It could be written in private message. Thanks =))

Nov 18, 2011 at 12:12 PM

 

These are just tags, of the created Styles in the applied template.

I create a docx, and the first i do, is apply the template with all the styles.

Once done that, i begin to write paragraphs and after create each paragraph set the StyleName with "Nivel1.... NivelN"=> Headers  and "Texto1....TextoN" for Text (but first paragraph), and "Textononum1.....TextononumN" to rest of text paragraphs.

So, styles defined as "Textononum1.... TextononumN" are a copy of "Texto1....TextoN" but without the number paragraph! 

        public static string TEMPLATE_HEADER = "Nivel";
        public static string TEMPLATE_NORMAL = "Texto";
        public static string TEMPLATE_NORMAL_NOT_NUMBERED = "Textononum";

This file, is the template i use, with all the Styles defined, open with Word and you'll see the differences between the styles.

https://docs.google.com/open?id=0B1yd7bR8agHIN2YyMjA3MjYtMGJjYS00M2IxLWI0NzYtYjJhYzY3OGVhNjc0

Dont worry for your English, for now i understand you told me ;)

Mine isnt the best neither :D

Regards

Developer
Nov 19, 2011 at 11:02 AM

Okey, I understand you. But I think that this functionality (different styles) you should write by hand... Also I have added Paragraph[] InsertParagraphs(string text) method, you can try to use it =) 

Nov 22, 2011 at 2:47 PM

 

Hi again!

I review the lastest version, thanks for adding the method, i'm changing my code now to work with it.

 

Only one thing, i´m running DocX over Net 3.5 and it compiles with no issues.

On lastest version, in InsertChart method of DocX.cs, i found this, specifically from .Net 4.0

// Save a chart info the chartPackagePart
chart.Xml.Save(chartPackagePart.GetStream(FileMode.Create, FileAccess.Write));

But it could be easily replace by:

// Save a chart info the chartPackagePart
using (TextWriter tw = new StreamWriter(chartPackagePart.GetStream(FileMode.Create, FileAccess.Write)))
	chart.Xml.Save(tw);

I tested your Explamples project, and everything keeps working fine, charts are generated right.

If you could modify the branch, and so, people like me, than want to use the benefits of latest version will have less problems (changes to do), 
each time you populate a new version to make it compile in .net 3.5

Best regards.
Miguel.
Developer
Nov 22, 2011 at 7:19 PM

Hi, thank you for this comment. I have chaged InsertChart method and commited it =)