【问题标题】:Transform Microsoft Excel .xls (NOT .xlsx) with Mule 4使用 Mule 4 转换 Microsoft Excel .xls(不是 .xlsx)
【发布时间】:2020-12-27 07:52:57
【问题描述】:

我们需要 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

这可能吗?

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

【问题讨论】:

    标签: java mule transformation xls mule4


    【解决方案1】:

    这是按照问题中的建议实现的。

    完成的示例流程如下所示:

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

    该文件随后被配置了 no mime 类型或编码的On New or Updated 文件阅读器读取。这是因为我们试图避免 Mule 知道有关文件类型的任何信息。当然可以以任何方式接收该文件 - 例如通过 FTP。

    此时,payload 看起来就像一堆 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
    • 参数:{arg0: payload as String}
    • 类:Java类的包和类名
    • 方法:调用的方法,我们的是transform(java.lang.String)

    它作为String 传递,因为Java 知道如何处理String 对象,基本上我们隐藏了它是一个文件的事实。

    从那里 Java 执行以下操作(请参阅上面的 Java 文件):

    • 解码文件:
    • 将其读取到 InputStream:
    • 创建 Apache POI 类:
    • 执行转换:

    在上面的示例中,我们只是将一个单元格的值作为字符串返回给 Mule。但是您也可以创建一个 CSV 类型的字符串,例如 a,b,c\nd,e,f(\n 表示换行),然后使用 Transform 事件将其转换为 CSV:

    %dw 2.0
    output application/java
    ---
    write( (read(payload,"application/csv",{"header" : false})),"application/csv",{"quoteValues" : "false","header" : false})
    

    会输出这样的 csv 文件:

    a,b,c
    d,e,f
    

    你有它。 Mule 现在可以处理 Microsoft Excel xls 文件。

    【讨论】:

    【解决方案2】:

    是的,您可以将 InputStream 传递给 Java 模块方法调用,并使用例如 Apache POI(也能够读取 xls 和 xlsx)将您的流转换为 csv。

    【讨论】:

    • 谢谢@maciej。我们没有设法使用 InputStream,而是使用 base64 将其编码为纯文本。
    猜你喜欢
    • 1970-01-01
    • 2013-01-25
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-11
    相关资源
    最近更新 更多