问题描述
我们需要Mule 4.3将旧的MS Excel 2003文件转换为CSV格式。我们无法控制源系统,因此不能选择以其他格式接收文件。
在mule site上指出他们不支持较早的格式,并且似乎也没有在线解决方法:
但是我想知道我们是否可以做这样的事情:
这有可能吗?
也许您可以提出其他解决方案?
解决方法
这是在问题中提出的。
添加Mule Java模块依赖项以及用于处理Microsoft xls文件的Apache POI:
<dependency>
<groupId>org.mule.module</groupId>
<artifactId>mule-java-module</artifactId>
<version>1.2.5</version>
<classifier>mule-plugin</classifier>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
然后,该文件由On New or Updated
文件阅读器读取,该文件阅读器配置了否哑剧类型或编码。这是因为我们试图避免Mule了解有关文件类型的任何信息。当然可以以任何方式接收文件-例如通过FTP。
这时,有效负载看起来像一堆gobbledygook(原始的xls文件)。
然后,源(文件阅读器)立即进行转换,将有效载荷转换为纯文本并对其进行base64编码:
%dw 2.0
import * from dw::core::Binaries
output text/plain
---
toBase64(payload as Binary)
之所以这样做,是因为最初我们在将原始文件传递给Java时遇到了很多麻烦,遇到了类似的问题(但是,如果您有更好的解决方案,请告诉我!):
- 不能这样转换为对象
- 文件结尾无效
这很合理,因为Java不知道我们要传递什么,因此它将如何将其转换为特定的对象类型。
接下来,我们使用Mule的Java'New'事件实例化Java类。该类本身看起来像:
public class Transformer {
public String transform(String file) {
String cellValue = "";
try {
// Decode base64:
byte[] decoded = Base64.getDecoder().decode(file);
// Steam decoded file to an input stream (as if we were reading it from disk)
InputStream targetStream = new ByteArrayInputStream(decoded);
// Create the .xls Apache POI object
HSSFWorkbook workbook = new HSSFWorkbook(targetStream);
// Process the rows/cells etc...
HSSFSheet sheet = workbook.getSheetAt(0);
// For example...
cellValue = sheet.getRow(0).getCell(0).getStringCellValue();
} catch (Exception e) {
System.out.println("FAIL" + e.getMessage());
}
return cellValue;
}
}
接下来,我们通过具有以下配置的Mule的Java Invoke事件将有效负载传递给此方法:
- 实例:vars.instanceName
- Args:
{arg0: payload as String}
- Class:Java类的包和类名
- 方法:要调用的方法,我们是transform(java.lang.String)
由于Java知道如何处理String
对象,因此它作为String
传递,并且基本上我们隐藏了它是文件的事实。
从那里Java执行以下操作(请参见上面的Java文件):
- 解码文件:
- 将其读取到InputStream:
- 创建Apache POI类:
- 执行转换:
在上面的示例中,我们只是将一个单元格的值作为String返回给Mule。但是,您也可以创建CSV类型的字符串,例如a,b,c\nd,e,f
(\ n代表新行),然后通过Transform事件将其转换为CSV:
%dw 2.0
output application/java
---
write( (read(payload,"application/csv",{"header" : false})),{"quoteValues" : "false","header" : false})
将输出如下所示的csv文件:
a,c
d,f
就在那里。 Mule现在可以处理Microsoft Excel xls文件。
,是的,您可以将InputStream传递给Java模块方法调用,并使用Apache POI(也可以读取xls和xlsx)将您的流转换为csv。