Replace styles in document from template

I have created a template with a set of custom styles to be used in all our documents.

I’d like to create a mini-script in Java which should do the following:

  • open the template
  • get all styles whose name starts with AGE_
  • copy the style to the target document, replacing it if it exists

Here is what I tried based on the docs at StyleCollection | Aspose.Words for Java :

Document source = new Document(args[0]);
Document target = new Document(args[1]);

System.out.println("SORGENTE = " + source.getStyles().getCount() + " stili");
System.out.println("DESTINAZIONE = " + target.getStyles().getCount() + " stili");

for (com.aspose.words.Style style : source.getStyles()) {
	String name = style.getName();

	if (name.substring(0, 4).equals("AGE_")) {
		System.out.println("COPIA STILE " + name);
		target.getStyles().addCopy(style).setName(name);
	}
}

System.out.println("FINALE = " + target.getStyles().getCount() + " stili");

target.save(args[args.length - 1]);

However, in the target document, I see the style is copied each time with a different suffix, like _0 then `_1 etc; how do I replace the existing style instead?

Also, this does not seem to work if I try to copy one of the default styles, I get an exception saying Cannot add a style because a style with this identifier already exists.

@mtassinari

Thanks for your inquiry. We will appreciate it if you please also share following resources as ZIP file. We will look into the scenario and will guide you accordingly.

  • Your input files
  • Existing output file
  • Expected output document

Hi,

I have attached a ZIP archive (update_styles.zip (14.5 KB)), which contains the following:

  • a template.doc, which I’d like to use to define our own styles for our templates
  • a target.doc, to which I want to replace the styles based on the name
  • a result.doc, which shows the result of applying the above snippet

As you can see in result.doc, the style has been modified, but there are also copies of it: for example, there are both AGE_titolo_paragrafo and AGE_titolo_paragrafo_0, but I do not want such duplicates.

How can I simply replace all AGE_* styles, based on name, while removing all duplicates?

EDIT:

I have noticed now that there are also other problems with my code, which I hope you can help me solve.

If I open template.doc and I open the “edit” window on style AGE_titolo_paragrafo I see this:
template_edit.png (15.7 KB)
The image clearly shows that the style is “based on” AGE_titolo_capitolo and should be “followed by” AGE_paragrafo.

However, if I open result.doc and do the same thing, I see something different:
result_edit.png (16.7 KB)
Here you can see that the options for “based on” and “followed by” differ from the template.

I created another test case, this time using only standard word styles.

In this case, not only the styles have been duplicate, but also the table “lost” the style Tabella 1 which was set on it.

update_styles_2.zip (15.4 KB)

It would be very important for us to create a Java “script” such that, given a template and a target document:

  • reads all styles defined in the template, both for text and tables
  • copies each style onto the target document, replacing the style if it already exists

To summarize, this is what I have come up until now, also based on the API reference at StyleCollection | Aspose.Words for Java

Document source = new Document(args[0]);
Document target = new Document(args[1]);

StyleCollection sourceStyles = source.getStyles();
StyleCollection targetStyles = target.getStyles();

System.out.println("SORGENTE = " + sourceStyles.getCount() + " stili");
System.out.println("DESTINAZIONE = " + targetStyles.getCount() + " stili");

for (Style style : sourceStyles) {
	String name = style.getName();

	if (
		name.startsWith("AGE_")
		&& (
			style.getType() == StyleType.PARAGRAPH
			|| style.getType() == StyleType.TABLE
		)
	) {
		Style copied = targetStyles.addCopy(style);
		System.out.println("COPIA STILE " + name + " -> " + copied.getName());
		copied.setName(name);
		copied.setBaseStyleName(style.getBaseStyleName());

		if (style.getType() == StyleType.PARAGRAPH) {
			copied.setNextParagraphStyleName(style.getNextParagraphStyleName());
		}
	}
}

// salvo il documento modificato
System.out.println("DOPO COPIA = " + targetStyles.getCount() + " stili");
String savepath = args[args.length - 1];
target.save(savepath);

As of now, the problems I have identified are the following:

  • if I tried using the standard MS Word styles (“Normal”, “Title 1”, …), when they’re copied over they get duplicated even using the setName() “trick”
  • if I instead use custom style, I have a problem with table styles, in which the text color changes

I think this all qualifies as “bug” in your library, I’d like to know if there is some workaround available, or else when they’ll be fixed?

@mtassinari

Thanks for your inquiry. We have tested the scenario with Aspose.Words for Java 17.9 and unable to notice change of Text color issue. Please find attached the output. Please download and try latest version of Aspose.Words for Java, it will resolve the issue. However, if there is any difference in your issue and our understanding then please share expected document with some more details. You may create expected document using MS Word.
result_179.zip (6.1 KB)

I am sorry, how can you not notice the issue?!

Especially in result2_179.doc you attached, the text clearly says:

This text should be WHITE with RED background

while instead it is BLACK with GREEN background!

In fact, if you open template2.doc in update_styles_2.zip, you’ll clearly see that the style Heading 1 is set to have white text and red background; I then changed target2.doc (in the same ZIP file) in order to prepare a test case, setting the Heading 1 style with black text and green background, and then run my code, trying to update/replace all styles in target2.doc with those in template2.doc and saving the result as result2.doc, and this clearly does not work.

I am attaching yet another test case (another_test.zip (123.2 KB)) which shows the issues:

  • the table style has not been update correctly
  • the table style copied is wrong, in fact Tabella 2 shows white text while in the template its black

I do not know what more examples show you to explain the issues; BTW, I am already using Aspose.Words version 17.9

@mtassinari

I am sorry for the inconvenience. I will appreciate it if you please share steps you follow to create expected.doc. It will help us to investigate and address your issue exactly. I have imported the styles from template.doc to target.doc using MS Word and noticed it shows same behavior as Aspose.Words for Java does.

I tried myself directly with MS Word, and I must say, you are right, the table does not get styled correctly because MS Word did not save the style associated to it… This would seem a bug in Word itself, actually, sorry for saying it was your library’s fault.

However, when using standard MS Word styles, the duplication problem still exists, as you can see in my result2.doc inside update_styles_2.zip.

@mtassinari,

For your first case, please use following code example to get the desired output. Please do not copy character styles whom name is ended with “Carattere”. Please also call Document.cleanup method before saving the document. We have attached the output document with this post for your kind reference.
output.zip (6.1 KB)

We are working over your second scenario and will get back to you soon.

Document source = new Document(MyDir + "template.doc");
Document target = new Document(MyDir + "target.doc");

StyleCollection sourceStyles = source.getStyles();
StyleCollection targetStyles = target.getStyles();

System.out.println("SORGENTE = " + sourceStyles.getCount() + " stili");
System.out.println("DESTINAZIONE = " + targetStyles.getCount() + " stili");

for (Style style : sourceStyles) {
    String name = style.getName();
    if (name.endsWith("Carattere")) continue;

    if (style.getType() == StyleType.PARAGRAPH
                            || style.getType() == StyleType.TABLE)
    {
        Style copied = targetStyles.addCopy(style);
        copied.setBaseStyleName(style.getBaseStyleName());

        if (style.getType() == StyleType.PARAGRAPH) {
           copied.setNextParagraphStyleName(style.getNextParagraphStyleName());
        }
        copied.setName(name);
        System.out.println("COPIA STILE " + name + " -> " + copied.getName());
    }
}

target.cleanup();
target.save(MyDir + "output.docx");

We have tested this scenario using same code example shared in my previous post and noticed that the text and background colors of paragraphs are correct. However, the style applied to first and second paragraphs are incorrect. It should be “Heading 1” for first paragraph and “Heading 2” for second paragraph. Please check the attached output document. awoutput.zip (2.6 KB)

For the sake of correction, we have logged this problem in our issue tracking system as WORDSNET-15961. You will be notified via this forum thread once this issue is resolved. We apologize for your inconvenience.

@mtassinari,

Thanks for your patience. Regarding WORDSNET-15961, we introduced new method Document.CopyStylesFromTemplate in the latest version of Aspose.Words. Please try this method to get the desired output. Hope this helps you.

The issues you have found earlier (filed as WORDSNET-15961) have been fixed in this Aspose.Words for .NET 19.1 update and this Aspose.Words for Java 19.1 update.