我使用 Aspose.cells (com.aspose:aspose-cells:24.12) 生成 Excel (.xlsx) 文件。
...
var outputStream = new ByteArrayOutputStream();
var workbook = new Workbook(inputStream);
workbook.save(entityStream, SaveFormat.XLSX);
生成的 xlsx 文件可以使用 MS Excel 应用程序打开,不会出现任何问题。然而,通过使用 Tika 库检查该文件的媒体类型来解决问题。 (org.apache.tika:tike-core:3.0.0)。为了检测媒体类型,我使用以下代码片段:
byte[] filecontent = ...
var result = new Tika().detect(filecontent)
Aspose 生成的文档的检测结果是 application/zip,而选择任何其他文档时检测到的类型是 application/x-tika-ooxml。
为了检查 xlsx 文件的内容,我将扩展名更改为 zip 并解压缩该文件。这是文件 [Content_Types].xml:
的内容<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" />
<Default Extension="xml" ContentType="application/xml" />
<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" />
<Override PartName="/xl/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml" />
<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml" />
<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml" />
<Override PartName="/docProps/custom.xml" ContentType="application/vnd.openxmlformats-officedocument.custom-properties+xml" />
<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml" />
<Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" />
<Override PartName="/xl/worksheets/sheet2.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" />
<Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml" />
</Types>
您发现此文件中存在任何问题吗? 此外,我还使用了一些在线 MimeTypes 检测工具,也检测到了 application/zip 类型。
我决定使用不同的方法进行 MediaType 检测,不是通过读取第一个魔术字节,而是在 Office 文档的情况下,深入研究内部 zip 结构并从 xml 文件中识别 MediaType。这可以用这样的代码来完成:
static TikaConfig TIKA_CONFIG = TikaConfig.getDefaultConfig();
static Detector DETECTOR = TIKA_CONFIG.getDetector();
static String detectMediaType(final byte[] filecontent, final String filename) {
final var metadata = new Metadata();
if (!ObjectUtils.isEmpty(filename)) {
metadata.add(TikaCoreProperties.RESOURCE_NAME_KEY, filename);
}
try (final var tikaInputStream = TikaInputStream.get(filecontent)) {
return DETECTOR.detect(tikaInputStream, metadata).toString();
} catch (IOException e) {
throw new RuntimeException(e);
}
}