Use the following code, I’m not able to copy all the styles correctly, the copied document contains wrong font size:
and here the source code which copy the styles:
import com.aspose.words.*;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class AsposeStyleCopierUtility {
private AsposeStyleCopierUtility() {
}
public static Document copyAllStyles(Document sourceDoc, Document targetDoc) {
for (Style sourceStyle : sourceDoc.getStyles()) {
// Check if the target document already has the style
if (targetDoc.getStyles().get(sourceStyle.getName()) == null) {
// If the target does not have the style, add a copy from the source
targetDoc.getStyles().addCopy(sourceStyle);
log.info("Added style: {}", sourceStyle.getName());
} else {
// If the target already has the style, update the target style properties
copyStyleProperties(sourceStyle, targetDoc.getStyles().get(sourceStyle.getName()), targetDoc);
log.info("Updated style: {}", sourceStyle.getName());
}
}
return targetDoc;
}
private static void copyStyleProperties(Style source, Style target, Document targetDoc) {
// Copy paragraph formatting if available
if (source.getType() == StyleType.PARAGRAPH && source.getParagraphFormat() != null) {
copyParagraphFormat(source.getParagraphFormat(), target.getParagraphFormat());
log.debug("Copied paragraph format for style: {}", source.getName());
}
// Copy table style properties if it's a table style
if (source.getType() == StyleType.TABLE && source instanceof TableStyle && target instanceof TableStyle) {
copyTableProperties((TableStyle) source, (TableStyle) target);
log.debug("Copied table style properties for style: {}", source.getName());
}
// Copy list properties if available (removing the redundant type check)
if (source.getListFormat() != null) {
copyListProperties(source, target, targetDoc);
log.debug("Copied list properties for style: {}", source.getName());
}
// Copy font settings for all styles that support font properties
if (source.getFont() != null) {
copyFont(source.getFont(), target.getFont());
log.debug("Copied font settings for style: {}", source.getName());
}
}
private static void copyFont(Font sourceFont, Font targetFont) {
targetFont.setName(sourceFont.getName());
if (sourceFont.getSize() > 0) {
targetFont.setSize(sourceFont.getSize());
}
targetFont.setBold(sourceFont.getBold());
targetFont.setItalic(sourceFont.getItalic());
targetFont.setUnderline(sourceFont.getUnderline());
targetFont.setColor(sourceFont.getColor());
targetFont.setStrikeThrough(sourceFont.getStrikeThrough());
targetFont.setSubscript(sourceFont.getSubscript());
targetFont.setSuperscript(sourceFont.getSuperscript());
targetFont.setAllCaps(sourceFont.getAllCaps());
targetFont.setSmallCaps(sourceFont.getSmallCaps());
// Copy additional font properties if required
}
private static void copyParagraphFormat(ParagraphFormat sourceFormat, ParagraphFormat targetFormat) {
targetFormat.setAlignment(sourceFormat.getAlignment());
targetFormat.setLeftIndent(sourceFormat.getLeftIndent());
targetFormat.setRightIndent(sourceFormat.getRightIndent());
targetFormat.setFirstLineIndent(sourceFormat.getFirstLineIndent());
targetFormat.setSpaceAfter(sourceFormat.getSpaceAfter());
targetFormat.setSpaceBefore(sourceFormat.getSpaceBefore());
targetFormat.setLineSpacing(sourceFormat.getLineSpacing());
targetFormat.setLineSpacingRule(sourceFormat.getLineSpacingRule());
targetFormat.setKeepTogether(sourceFormat.getKeepTogether());
targetFormat.setKeepWithNext(sourceFormat.getKeepWithNext());
targetFormat.setPageBreakBefore(sourceFormat.getPageBreakBefore());
targetFormat.setWidowControl(sourceFormat.getWidowControl());
// Copy additional paragraph formatting properties if required
}
private static void copyTableProperties(TableStyle sourceStyle, TableStyle targetStyle) {
targetStyle.setAllowBreakAcrossPages(sourceStyle.getAllowBreakAcrossPages());
targetStyle.setLeftIndent(sourceStyle.getLeftIndent());
targetStyle.setBottomPadding(sourceStyle.getBottomPadding());
targetStyle.setTopPadding(sourceStyle.getTopPadding());
targetStyle.setLeftPadding(sourceStyle.getLeftPadding());
targetStyle.setRightPadding(sourceStyle.getRightPadding());
targetStyle.setRowStripe(sourceStyle.getRowStripe());
targetStyle.setColumnStripe(sourceStyle.getColumnStripe());
// Copy additional table style properties if required
}
private static void copyListProperties(Style source, Style target, Document targetDoc) {
if (source.getListFormat() != null) {
List sourceList = source.getListFormat().getList();
if (sourceList != null) {
// Check if the target document already has a list with the same definition
List targetList = findMatchingList(targetDoc, sourceList);
if (targetList == null) {
// If not, add a copy of the source list to the target document
targetList = targetDoc.getLists().addCopy(sourceList);
log.info("Added new list for style: {}", source.getName());
}
// Associate the target style with the copied list
target.getListFormat().setList(targetList);
target.getListFormat().setListLevelNumber(source.getListFormat().getListLevelNumber());
}
}
}
private static List findMatchingList(Document targetDoc, List sourceList) {
for (List list : targetDoc.getLists()) {
if (listsAreEqual(list, sourceList)) {
return list;
}
}
return null;
}
private static boolean listsAreEqual(List list1, List list2) {
// A more thorough comparison can be implemented here if needed
return list1.equals(list2);
}
}
@giuseppe.elmota
It seems that you are experiencing issues with copying styles, particularly with font sizes not being transferred correctly from the source document to the target document. This can happen due to various reasons, including font availability and settings.
Here are a few suggestions to help you troubleshoot and potentially resolve the issue:
-
Ensure Font Availability: Make sure that the fonts used in the source document are available on the system where the target document is being processed. If the required fonts are not installed, Aspose.Words may substitute them with default fonts, which can lead to discrepancies in font size and style.
-
Use FontSettings: You can specify font settings explicitly when loading documents. This can help ensure that the correct fonts are used during the rendering process. For example, you can set the font sources to include directories where your fonts are located:
FontSettings fontSettings = new FontSettings();
fontSettings.setFontsFolders(new String[] { "C:\\MyFonts", "D:\\OtherFonts" }, true);
Document doc = new Document("source.docx", new LoadOptions() {{ setFontSettings(fontSettings); }});
-
Check Font Substitution Settings: If the fonts are not found, Aspose.Words will apply font substitution rules. You can customize these rules to ensure that the desired fonts are used. For example, you can set a default font to be used when the specified font is not available:
FontSettings fontSettings = new FontSettings();
fontSettings.getSubstitutionSettings().getDefaultFontSubstitution().setDefaultFontName("Arial");
-
Debugging Font Issues: Implement a warning callback to capture any font substitution warnings. This can help you identify which fonts are being substituted and why:
doc.setWarningCallback(new IWarningCallback() {
public void warning(WarningInfo info) {
if (info.getWarningType() == WarningType.FONT_SUBSTITUTION) {
System.out.println("Font substitution: " + info.getDescription());
}
}
});
-
Review Your Copying Logic: Ensure that your logic for copying styles is correctly implemented. You might want to double-check the copyFont
method to ensure that all relevant font properties are being copied correctly.
By following these steps, you should be able to address the font size issues you are encountering when copying styles between documents. If the problem persists, consider providing more details about the specific fonts and styles involved for further assistance.
Sources:
[1]: FontSettings | Aspose.Words for Java
[2]: Manipulate and Substitute TrueType Fonts
@giuseppe.elmota Could you please attach your input, output and expected output documents here for testing? We will check the issue and provide you more information.
Perhaps it would be easier to copy content to the document with the required styles to get the expected output.
I cannot attach the document because it contains private data.
I can say that the original document contains a style called “Body Text | Ref Note”, with Font “Avenir Next LT Pro” and no size.
But, after copying style to a new document, the style is called “Body Text | Ref Note” and has Font “Avenir Next LT Pro” and size 8.
How can I avoid this behavior? Because it will propagate on derived styles
@giuseppe.elmota Unfortunately, without documents it is hard to answer what causes the problem. Have you considered the suggestion above, i.e. copy content into the document with required styles, instead of copying style to the document with content?
Thanks for the reply, unfortunately I added the code to copy the style due to not working style copying when use copy content with “ImportFormatMode.KeepSourceFormatting”.
I’ll try to share document without private content soon
1 Like
Please find attached the input template document (.dotx) and the output from the copy (.docx).
You can notice that the font and size are the same but the style name and his parent style are different.
NewPowerCorp.zip (159.8 KB)
@giuseppe.elmota Thank you for additional information, but unfortunately, it is still not quite clear how to reproduce the problem and what is the expected output. Could you please provide runnable code that will allow us to reproduce the problem? Also, please attach the expected output for our reference.
Please find attached the 2 Java classes and the expected output docx
CorrectOutput.docx (184.7 KB).
We use applyStyleTemplate(byte[] content, byte[] template, boolean copyContent) with copyContent as true.
AsposeStyleTemplateCode.zip (2.9 KB)
I hope they can help investigating
@giuseppe.elmota Thank you for additional information. So your expected output uses the styles defined in the template document. To achieve this, you can simply used the following code:
Document template = new Document("C:\\Temp\\temple.dotx");
Document doc = new Document("C:\\Temp\\source.docx");
// Remove content from the template.
template.removeAllChildren();
// Append the source document content into the template using the template styles.
template.appendDocument(doc, ImportFormatMode.USE_DESTINATION_STYLES);
template.save("C:\\Temp\\out.docx");
When ImportFormatMode.USE_DESTINATION_STYLES
mode is used, if a matching style already exists in the destination document, the style is not copied and the imported nodes are updated to reference the existing style. So if your template has Title
style and in your source document there is content formatted with Title
style, the style from the template will be applied to the copied content.
In addition, there is a built-in method to copy styles between the documents, see Document.copyStylesFromTemplate
. When styles are copied from a template to a document, like-named styles in the document are redefined to match the style descriptions in the template. Unique styles from the template are copied to the document. Unique styles in the document remain intact.
In your code you explicitly set properties of the copied styles, this breaks inheritance, since getters of style properties return actual values of the properties, which might be inherited and are not set explicitly. but when you use setter the value is set explicitly in the style and overrides the inherited value.
Thanks @alexey.noskov , I’m testing this solution. I have only one question to make sure this is the right solution: Does the appendDocument copy also all the customxml elements?
@giuseppe.elmota It is required to test the scenario to be sure. So, please attach sample documents or test the scenario on your side.