获取word文件中所有字体

我想获取一个word文件中所有字体名称,是否有提供api,另外,我也想获取当前机器上所有已安装的字体,是否有办法?

@humanhuman, 这是获取所有已安装字体的方法:

FontSettings fontSettings = new FontSettings();

for (var fontSource : fontSettings.getFontsSources())
{
    for (var font: fontSource.getAvailableFonts())
    {
        System.out.println("FullName: ["+ font.getFullFontName() + "], FamilyName:[" + font.getFontFamilyName()+"]");
    }
}

您可以使用 Document.getFontInfos()方法获取 Word 文档中指定的所有字体的列表。 但是,此列表可能包含 Word 文档中未使用的字体。

 Document doc = new Document("in.docx");

 FontInfoCollection allFonts = doc.getFontInfos();
 // Print all the used and unused fonts in the document.
 for (int i = 0; i < allFonts.getCount(); i++) {
     System.out.println("Font index #{i}");
     System.out.println("\tName: {allFonts[i].Name}");
 }

另一种方法是检查文档中的所有元素并检查指定的字体:

Document doc = new Document("in.docx");

FontInspector fontInspector = new FontInspector();
doc.accept(fontInspector);

for (String fontName : fontInspector.fonts) {
    System.out.println(fontName);
}
public static class FontInspector extends DocumentVisitor {
        public HashSet<String> fonts = new HashSet<String>();
    private void saveFont(Font font)
    {
        fonts.add(font.getName());
        fonts.add(font.getNameFarEast());
        fonts.add(font.getNameBi());
        fonts.add(font.getNameAscii());
        fonts.add(font.getNameOther());
    }

    /// <summary>
    /// Called when a FieldEnd node is encountered in the document.
    /// </summary>
    @Override
    public int visitFieldEnd(FieldEnd fieldEnd)
    {
        //Simply change font name
        saveFont(fieldEnd.getFont());
        return VisitorAction.CONTINUE;
    }

    /// <summary>
    /// Called when a FieldSeparator node is encountered in the document.
    /// </summary>
    @Override
    public int visitFieldSeparator(FieldSeparator fieldSeparator)
    {
        saveFont(fieldSeparator.getFont());
        return VisitorAction.CONTINUE;
    }

    /// <summary>
    /// Called when a FieldStart node is encountered in the document.
    /// </summary>
    @Override
    public int visitFieldStart(FieldStart fieldStart)
    {
        saveFont(fieldStart.getFont());
        return VisitorAction.CONTINUE;
    }

    /// <summary>
    /// Called when a Footnote end is encountered in the document.
    /// </summary>
    @Override
    public int visitFootnoteEnd(Footnote footnote)
    {
        saveFont(footnote.getFont());
        return VisitorAction.CONTINUE;
    }

    /// <summary>
    /// Called when a FormField node is encountered in the document.
    /// </summary>
    @Override
    public int visitFormField(FormField formField)
    {
        saveFont(formField.getFont());
        return VisitorAction.CONTINUE;
    }

    /// <summary>
    /// Called when a Paragraph end is encountered in the document.
    /// </summary>
    @Override
    public int visitParagraphEnd(Paragraph paragraph)
    {
        saveFont(paragraph.getParagraphBreakFont());
        return VisitorAction.CONTINUE;
    }

    /// <summary>
    /// Called when a Run node is encountered in the document.
    /// </summary>
    @Override
    public int visitRun(Run run)
    {
        saveFont(run.getFont());
        return VisitorAction.CONTINUE;
    }

    /// <summary>
    /// Called when a SpecialChar is encountered in the document.
    /// </summary>
    @Override
    public int visitSpecialChar(SpecialChar specialChar)
    {
        saveFont(specialChar.getFont());
        return VisitorAction.CONTINUE;
    }
}

我尝试了提供的代码示例,确实可以准确获取到字体,但是我发现获取系统全部字体时,获取到的是familyName,而从文档中获取到的字体是字体名称。比如宋体这种字体,系统中获取到是:SimSun。文档中获取到的是:宋体。能不能两边获取到是一致的?
image.jpg (76.2 KB)
image.png (53.6 KB)

@humanhuman, 对于不同的区域设置,字体可以有不同的名称。 下面的屏幕截图显示了不同区域设置的名称如何以 SimSun 字体存储:

Aspose.Words 不提供公共 API 来根据区域设置访问字体名称。 但您可以使用 java.awt.Font 类,如下面的代码示例所示:

FontSettings fontSettings = new FontSettings();

for (var fontSource : fontSettings.getFontsSources())
{
    for (var font: fontSource.getAvailableFonts())
    {
        var awtFont = java.awt.Font.createFont(Font.TRUETYPE_FONT, new File(font.getFilePath()));
        // Get the font name for Chinese locale
        String chineseName  = awtFont.getFamily(Locale.CHINA);

        System.out.print("FullName: ["+ font.getFullFontName() + "], FamilyName:[" + font.getFontFamilyName()+"], ");
        System.out.println("Chinese: [" + chineseName + "]");
    }
}

1 Like