使用Mule 4转换Microsoft Excel .xlsNOT .xlsx

问题描述

我们需要Mule 4.3将旧的MS Excel 2003文件转换为CSV格式。我们无法控制源系统,因此不能选择以其他格式接收文件

mule site上指出他们不支持较早的格式,并且似乎也没有在线解决方法

支持.xlsx文件(Excel 2007)。 Mule不支持.xls文件

但是我想知道我们是否可以做这样的事情:

  1. 将输入作为“ blob”读取,没有相关格式
  2. 立即将其交给Mule 4 Java模块
  3. Java模块将使用Java插件进行转换
  4. 将转换后的有效负载作为CSV传递回dataweave

这有可能吗?

也许您可以提出其他解决方案?

解决方法

这是在问题中提出的。

完成的样本流如下所示: Mule flow

添加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。