Aspose.word for android 关于txt转pdf 中文乱码问题

File originFile = new File(uriFile);
String text = "";
FileInputStream fileInputStream = new FileInputStream(originFile.getAbsoluteFile());
byte[] buf = new byte[fileInputStream.available()];
int length = 0;
//循环读取文件内容,输入流中将最多buf.length个字节的数据读入一个buf数组中,返回类型是读取到的字节数。
//当文件读取到结尾时返回 -1,循环结束。
ExchangeUtil s = new ExchangeUtil();
while ((length = fileInputStream.read(buf)) != -1)
{
    text = new String(buf, 0, length, ExchangeUtil.javaname[s.detectEncoding(originFile)]);
}
// Address是将要被转化的word文档
doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.write(text);
doc.save(os, com.aspose.words.SaveFormat.PDF);
fileInputStream.close();

exchangeutils和txt文件.zip (95.5 KB)

@aaron0309 能否附上输出的 pdf 文件,以获取有关问题的信息。

@aaron0309 可能是字体问题。请查看以下文章: Specify TrueType Fonts Location in Java|Aspose.Words for Java. 您可以通过以下代码将所需字体复制到设备并设置字体文件夹:

FontSettings fontSettings = new FontSettings();
fontSettings.setFontsFolder(rootDir + "/MyFonts/", false);
doc.setFontSettings(fontSettings);

短点从地球到月球_1714990129137.pdf (63.3 KB)

// 实例化FontSettings对象
FontSettings fontSettings = new FontSettings();
// 添加中文字体映射,假设“宋体”是系统中可用的中文字体
fontSettings.setFontsFolder("/system/fonts/Roboto-Regular.ttf", false);
...
doc.setFontSettings(fontSettings);
doc.save(os, com.aspose.words.SaveFormat.PDF);

添加手机自带的字体还是不行。添加之后中文还是口口。

@aaron0309 您在文档中添加了文本,而文档默认使用 Times New Roman。根据文档,默认情况下 Times New Roman 将被 NotoSerif 字体替代。此外,您应在代码中提供字体文件夹,而不是字体。我认为 Roboto 不能包含中文符号,因此我建议您使用 SimSun 等字体。您可以用以下方法修改代码,然后用 Roboto 字体检查结果:

FontSettings fontSettings = FontSettings.getDefaultInstance();
fontSettings.setFontsSources(
        new FontSourceBase[] { new SystemFontSource(), new FolderFontSource(rootDir + "/MyFonts/", true) });
fontSettings.getSubstitutionSettings().getTableSubstitution().setSubstitutes("Times New Roman", "Roboto");
doc.setFontSettings(fontSettings);

不过,您也可以将字体添加到自定义字体文件夹并配置替代字体。

能否提供demo,或者完整代码。尝试几次修改后依然无法解决。感谢!

@aaron0309 下面是一个简单的应用程序,里面有我使用过的字体:

我在下载文件夹中添加了文件:


能否把转换后的文件提供一下,另外还有别的方式实现吗?字体文件太大不太好处理。

@aaron0309 将此文本插入 MS Word 时,使用的是 SimSun 字体。此外,我还尝试使用 "Noto Sans SC "字体。下面是使用这些字体的结果:

ResultNotoSans.pdf (1.2 MB)
ResultSimSun.pdf (742.7 KB)

我在我的安卓模拟器上找不到任何带有中文字体的字体。也许你有这样的字体,可以使用它。我在这里找到了字体:Browse Fonts - Google Fonts

此外,您还可以尝试使用以下代码来设置需要使用的字体:

FontSettings fontSettings = FontSettings.getDefaultInstance();
fontSettings.setFontsFolder(rootDir + "/MyFonts", false);
doc.setFontSettings(fontSettings);

DocumentBuilder builder = new DocumentBuilder(doc);
builder.getFont().setName("Noto Sans SC");
builder.write(text);

我尝试你们提供的方法和demo,还是依然无法转换成功,显示乱码情况。

String rootDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString();

File originFile = new File(uriFile);
String text = "";
try (FileInputStream fileInputStream = new FileInputStream(originFile.getAbsoluteFile())) {
    byte[] buf = new byte[fileInputStream.available()];
    int length = 0;

    ExchangeUtil s = new ExchangeUtil();
    while ((length = fileInputStream.read(buf)) != -1)
    {
        text = new String(buf, 0, length, ExchangeUtil.javaname[s.detectEncoding(originFile)]);
    }
}

Document docTxt = null;
try
{
    docTxt = new Document();

    HandleDocumentWarnings callback = new HandleDocumentWarnings();
    docTxt.setWarningCallback(callback);

    FontSettings fontSettings = FontSettings.getDefaultInstance();
    fontSettings.setFontsSources(
            new FontSourceBase[] { new SystemFontSource(), new FolderFontSource(rootDir + "/MyFonts/", true) });
    docTxt.setFontSettings(fontSettings);

    DocumentBuilder builder = new DocumentBuilder(docTxt);
    builder.write(text);

    docTxt.save(os, SaveFormat.PDF);
}
catch (Exception e)
{
    e.printStackTrace();
}

短点从地球到月球_1715227741153.pdf (66.8 KB)

@aaron0309 如果使用 simsunb 字体,则应通过以下步骤之一设置字体:

FontSettings fontSettings = FontSettings.getDefaultInstance();
fontSettings.setFontsSources(
            new FontSourceBase[] { new SystemFontSource(), new FolderFontSource(rootDir + "/MyFonts/", true) });
fontSettings.getSubstitutionSettings().getTableSubstitution().setSubstitutes("Times New Roman", "SimSun-ExtB");
doc.setFontSettings(fontSettings);

或者直接设置:

builder.getFont().setName("SimSun-ExtB");
builder.write(text);

这是字体的名称:

正如我所说,在文档中插入文本时,Aspose.Words 默认使用 Times New Roman 字体。因此,您需要指定字体替换,或在文档生成器中设置字体。

以上方法都全部尝试了。依然无法正常转换。转换中文文档依旧口口。。。乱码字样,英语是正常的。我们的需求并不需要指定simsunb 字体。只需要能够正常转换。不出现中文乱码就行。 中文.Word文档转换PDF,不会出现该情况。TXT文档转换需要特别处理吗?

我们目前接入的是aspose.word-android,请问下文档转换字体匹配规则问题。如果遇到文档转换出现字体不兼容问题。是否需要存储大量字体文件,如果是这样的话,如果字体库的数量太多了。有没其他兼容方式?

@aaron0309 如果您查看随附的 PDF,您会发现 PDF 文档仅使用 NotoSerif 字体:

因此,Aspose.Words 似乎无法喜欢或访问所提供的字体。 IWarningCallback 是否显示有关您这边字体替换的警告? 您还可以尝试在字体源中设置警告回调,以检查从指定源加载字体是否存在问题。
https://reference.aspose.com/words/java/com.aspose.words/fontsourcebase/#setWarningCallback-com.aspose.words.IWarningCallback

最后,为了确保可以加载字体,您可以将其读入流并使用 StreamFontSource 来排除文件访问问题。

不幸的是,如果没有字体,就无法正确构建文档布局并呈现文档。 因此,Word 到 PDF 转换需要字体。

FontSettings fontSettings = FontSettings.getDefaultInstance();
fontSettings.setFontsSources(
new FontSourceBase[]{new SystemFontSource(), new FolderFontSource(rootDir+“/”, true)});
fontSettings.getSubstitutionSettings().getTableSubstitution().setSubstitutes(“Times New Roman”, “SimSun-ExtB”);
docTxt.setFontSettings(fontSettings);

                        DocumentBuilder builder = new DocumentBuilder(docTxt);
                        builder.getFont().setName("SimSun-ExtB");

// builder.write(“这是一段示例文本。”);
builder.write(text);

微信图片_20240516134323.png (17.2 KB)
短点从地球到月球_1715838116089.pdf (78.6 KB)

微信图片_20240516135007.png (76.9 KB)

按照上面要求把字体设置成SimSun-ExtB之后字体还是乱码口口口,

@aaron0309 我可以用 SimSun-ExtB 字体重现这个问题。这种字体还需要使用 HarfBuzz 库。您可以使用以下代码:

doc = new Document();
doc.getLayoutOptions().setTextShaperFactory(HarfBuzzTextShaperFactory.getInstance());

但看起来 SimSun-ExtB 文件中也没有使用某些字形。因此,我建议您使用原始的 SimSun 字体。
simsun-orig.zip (9.2 MB)

您还可以使用文档类直接打开 txt 文件。

doc = new Document(rootDir + "/input.txt");
doc.getLayoutOptions().setTextShaperFactory(HarfBuzzTextShaperFactory.getInstance());

HandleDocumentWarnings callback = new HandleDocumentWarnings();
doc.setWarningCallback(callback);

FontSettings fontSettings = FontSettings.getDefaultInstance();
fontSettings.setFontsFolder(rootDir + "/MyFonts", false);
fontSettings.getSubstitutionSettings().getTableSubstitution().setSubstitutes("Times New Roman", "SimSun");
doc.setFontSettings(fontSettings);

try (FileOutputStream outputStream = new FileOutputStream(resultFile)) {
    doc.save(outputStream, SaveFormat.PDF);
}

使用了 HarfBuzz 库,目前在使用上述代码:

doc = new Document(uriFile);
doc.getLayoutOptions().setTextShaperFactory(HarfBuzzTextShaperFactory.getInstance());

HandleDocumentWarnings callback = new HandleDocumentWarnings();
doc.setWarningCallback(callback);

FontSettings fontSettings = FontSettings.getDefaultInstance();
fontSettings.setFontsFolder(rootDir, false);
fontSettings.getSubstitutionSettings().getTableSubstitution().setSubstitutes("Times New Roman", "SimSun");
doc.setFontSettings(fontSettings);

doc.save(os, SaveFormat.PDF);

生成之后还是错误乱码。
短点从地球到月球_1715853820321.pdf (71.5 KB)

原始的 SimSun 字体下载后是ttc格式,Android好像不支持改格式字体。
微信图片_20240516181010.png (3.9 KB)

@aaron0309 遗憾的是,我这边无法重现这种行为。在我的应用程序中,即使没有表格替换也能正常工作,Aspose.Words 使用字体文件夹查找所需字体:

FontSettings fontSettings = FontSettings.getDefaultInstance();
fontSettings.setFontsFolder(rootDir + "/MyFonts", false);
doc.setFontSettings(fontSettings);

您能否在此分享您的测试应用程序,以便我们尝试重试并检查发生了什么?