Copy Styles without copying content- like MS Word's organizer?

Is there a way to copy all styles from one document to another without copying content, similar to how you would copy styles between templates/documents in MS Word using the organizer? I could use all of the styles on content, copy that content, and then delete it–but that doesn’t seem like a good solution.
Thanks.

Hi
Thanks for your remark. Unfortunately Aspose.Words hasn’t import styles feature from document to another document yet.
But I have logged this problem to our defect base as issue # 3286. We will try to fix it in our next release, which will be published in a couple of weeks. A notification will be posted here in this thread as soon as it will be done.

Any update on this functionality? Thanks

We are working on it. Thank you for your patience.

There IS a way to move styles into a document ONLY if they don’t already exist in the destination document. As far as I can tell, there is STILL NO WAY to simply replace a style that already exists (if you’re applying a new style template, for example). In addition, there is no way to delete a style. The style management capabilities are quite poor in this product… which is surprising, since I (along with others) have been bugging Aspose to provide such capabilities for YEARS! It was July 2007 when you suggested that you were working on this issue. Do you intend to ever provide this capability? We’d like to know.
Years ago, we moved to Aspose to try to perform actions on the server, rather than the client, because we thought it would be faster. Due to a variety of issues (including this one), we are now reversing that decision, and starting to minimize the use of Aspose, because it increasingly does not meet our needs, and often makes the situation worse.

Hi Jason,
Thanks for your inquiry
I’m afraid there is still no way to replace or remove styles in a document. We will look into supporting this as soon as possible.
For now, you can use the work around provided by Alexey here to copy styles between documents.
We apologise for any inconvenience.
Thanks,

So, maybe you can help me with a workaround that will actually work. So, say we have a document, and a template, and the document has Style A defined. There is no way to overwrite Style A in that document with Style A from the template. What we’ve done in the past is create a blank document (without Style A), copy the styles from the template, then copy the content from the document. But the problem is there are a lot of things from the original document that we may lose. Can you provide a workaround that uses this concept, but preserves things like margins, paper size, orientation, and document properties?

Hi there,
Thanks for your inquiry.
I think you may be having these issues because you are inserting the content at the block node level. If you append each section from the source document then you should not have these issues regarding formatting changes. Please see the code below.

Document srcDoc = new Document("Document1.doc");
Document tempDoc = new Document();
tempDoc.RemoveAllChildren();
tempDoc.AppendDocument(srcDoc, ImportFormatMode.UseDestinationStyles);
tempDoc.Save("Document Out.doc");

The document properties will still however be modified, you can try using the code below to copy these automatically using reflection.

CopyObjectProperties(srcDoc.BuiltInDocumentProperties, tempDoc.BuiltInDocumentProperties);
public static void CopyObjectProperties(Object source, Object dest)
{
    if (source.GetType() != dest.GetType())
        throw new ArgumentException("All objects must be of the same type");
    // Iterate through each property in the source object.
    foreach (PropertyInfo prop in source.GetType().GetProperties())
    {
        // Skip indexed access items. Skip setting the internals of a style as these should not be changed.
        // Skip properties that return any class derived from Node or NodeCollection
        if (prop.Name == "Item" || prop.Name == "Style" || prop.GetGetMethod().ReturnType == null || IsSubclassOfRawGeneric(typeof(Node), prop.GetGetMethod().ReturnType) || IsSubclassOfRawGeneric(typeof(NodeCollection), prop.GetGetMethod().ReturnType))
            continue;
        object value;
        // Wrap this call as it can throw an exception. Skip if thrown
        try
        {
            value = prop.GetValue(source, null);
        }
        catch (Exception)
        {
            continue;
        }
        // Skip if value can not be retrieved.
        if (value != null)
        {
            // If this property returns a class which belongs to the 
            if (value.GetType().IsClass && prop.GetGetMethod().ReturnType.Assembly.ManifestModule.Name == "Aspose.Words.dll")
            {
                // Recurse into this class.
                CopyObjectProperties(prop.GetValue(source, null), prop.GetValue(dest, null));
            }
            else if (prop.CanWrite)
            {
                // If we can write to this property then copy the value across.
                prop.SetValue(dest, prop.GetValue(source, null), null);
            }
        }
    }
}

If you have any further queries, please feel free to ask.
Thanks,

Ok, sounds promising. Do you have the same code in VB.NET?
Also, does Clone preserve document properties? If so, in future releases, you could provide a version of Clone that doesn’t copy styles. That way, we could clone the document without children or styles (this would result in the document shell). Then we could copy in the styles, then bring in the content using the example you provided above.

Hi there,
Sure, please find the translated code below.

Dim srcDoc As New Document("Document1.doc")
Dim tempDoc As New Document()
tempDoc.RemoveAllChildren()
tempDoc.AppendDocument(srcDoc, ImportFormatMode.UseDestinationStyles)
tempDoc.Save("Document Out.doc")
Public Shared Sub CopyObjectProperties(ByVal source As Object, ByVal dest As Object)
If source.GetType() IsNot dest.GetType() Then
Throw New ArgumentException("All objects must be of the same type")
End If
' Iterate through each property in the source object.
For Each prop As PropertyInfo In source.GetType().GetProperties()
' Skip indexed access items. Skip setting the internals of a style as these should not be changed.
' Skip properties that return any class derived from Node or NodeCollection
If prop.Name = "Item" OrElse prop.Name = "Style" OrElse prop.GetGetMethod().ReturnType Is Nothing OrElse IsSubclassOfRawGeneric(GetType(Node), prop.GetGetMethod().ReturnType) OrElse IsSubclassOfRawGeneric(GetType(NodeCollection), prop.GetGetMethod().ReturnType) Then
Continue For
End If
Dim value As Object
' Wrap this call as it can throw an exception. Skip if thrown
Try
value = prop.GetValue(source, Nothing)
Catch e1 As Exception
Continue For
End Try
' Skip if value can not be retrieved.
If value IsNot Nothing Then
' If this property returns a class which belongs to the 
If value.GetType().IsClass AndAlso prop.GetGetMethod().ReturnType.Assembly.ManifestModule.Name = "Aspose.Words.dll" Then
' Recurse into this class.
CopyObjectProperties(prop.GetValue(source, Nothing), prop.GetValue(dest, Nothing))
ElseIf prop.CanWrite Then
' If we can write to this property then copy the value across.
prop.SetValue(dest, prop.GetValue(source, Nothing), Nothing)
End If
End If
Next prop
End Sub
Shared Function IsSubclassOfRawGeneric(ByVal generic As Type, ByVal toCheck As Type) As Boolean
Do While toCheck IsNot GetType(Object)
Dim cur = If(toCheck.IsGenericType, toCheck.GetGenericTypeDefinition(), toCheck)
If generic Is cur Then
Return True
End If
toCheck = toCheck.BaseType
Loop
Return False
End Function

Regarding the clone method, yes it does copy document properties. We will consider adding an overload so styles are not copied during cloning. We will keep you informed of any developments.
Thanks,

Thanks. A few issues with the code:

  1. Unless you are importing System.Reflection, you will need to change:
    prop As PropertyInfo
    To:
    prop As System.Reflection.PropertyInfo
  2. The variable cur will require a type if using Option Strict:
    Dim cur As Type
  3. Unless you’re importing Aspose.Words, you’ll need to fully qualify Node and NodeCollection.

Once those are fixed, it seems to work for the most part. I noticed the background color of the document doesn’t come over when Appending the document. I’m in Office 2007 working with an Office 2003 format document and template.

Hi Jason,
Thanks for your inquiry.
The paper color used for a document is separate from each section. You can find this property under
Document.PaperColor. While calling the other code you can also call dstDoc.PaperColor = srcDoc.PaperColor;
Thanks,

Can you give any advice as to what other properties or formatting we may lose using the AppendDocument workaround?

Hi
Thanks for your request. If you merge document, then all Document properties of the source document will be lost, like BuildInDocumentProperties, CustomDocumentProperties and other properties specified for a document. But all formatting properties of source document’s content will be preserved.
Best regards,

Hi Jason,

The functionality offered by the MS Word Organizer to copy styles is seemingly deceptive. It does quite a work behind the scenes. Every time I come decided to work out suitable use cases for Aspose.Words copy styles between documents I get put off by the number of intricacies that might arise. Styles can reference other styles, they can also reference lists, which in turn can also reference styles, brrr.

So, for example, if you want to copy Heading 1 from document A to document B, but document B has Heading 1 already? Okay, we might replace Heading 1 in B. But Heading 1 in A is based on Normal, which is also defined in A. What do you want to do with the Normal style? If you don’t copy Normal from A to B, then Heading 1 in B might look different to what you expect. But if you copy Normal from A over to B, then everything in B might start to look different. That sort of thing.

Tell me more about your scenario if you still need to copy styles please.

In my case, we have content (doc, docx, and docm) and templates (dot, dotx, dotm). When we deliver a piece of content via a web application, we want to apply the styles from the template.
So, for this scenario, it would be appropriate for all styles in the template to be copied to the document, overwriting any styles with the same name, but leaving any other styles in place.
The workarounds we’ve seen are:

  1. Create a line of text in the template for each style, apply the styles to each line, use AppendDocument to import the content into the document using KeepSourceFormatting, then delete the extra lines of text.
  2. Create a document from the template, clear all content from the template, use AppendDocument to import the content into the template using UseDestinationStyles, then delete the extra paragraph.

Both approaches have significant challenges.
I’d like to see something like: document.ImportStyles(template)

Hi Jason,

Thanks for your inquiry.

It sounds like you can achieve what you are looking for by simply loading the template document as a base and appending the content from the source document using ImportFormatMode.UseDestinationStyles.

  • For a style which already exists in the template document it will apply this style from the template to all incoming content.
  • If a style exists only in the source document and not the template then it will be imported into the template document…

Please see the code below for an example.

Document baseDoc = new Document("Template.dotx");
Document contentDoc = new Document("Content.docx");
baseDoc.AppendDocument(contentDoc, ImportFormatMode.UseDestinationStyles);

Thanks,

The issues you have found earlier (filed as WORDSNET-1268) have been fixed in this .NET update and this Java update.

This message was posted using Notification2Forum from Downloads module by aspose.notifier.
(11)