代码之家  ›  专栏  ›  技术社区  ›  Continuity8

使改变带Mule 4的xls(非.xlsx)

  •  0
  • Continuity8  · 技术社区  · 6 年前

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

    上 mule site

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

    1. 将输入读取为没有关联格式的“blob”
    2. 立即将其交给Mule 4 Java模块
    3. Java模块将使用Java插件进行转换

    这有可能吗?

    也许你可以提出另一个解决方案?

    0 回复  |  直到 6 年前
        1
  •  1
  •   Continuity8    6 年前

    这是问题中提出的。

    Mule flow

    添加Mule Java模块依赖项和Apache POI以处理Microsoft xls文件:

        <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 已配置mime类型或编码。这是因为我们试图避免Mule知道任何关于文件类型的信息。当然,可以通过任何方式接收文件-例如通过FTP。

    此时,有效负载看起来就像一堆gobbledygook(原始xls文件)。

    %dw 2.0
    import * from dw::core::Binaries
    output text/plain
    ---
    toBase64(payload as Binary)
    

    之所以这样做,是因为最初我们在将原始文件传递给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。实例名
    • Args: {arg0: payload as String}
    • Class:Java类的包和类名
    • 方法:调用的方法是transform(java.lang.String)

    String 因为Java知道如何处理 一串

    Java从中执行以下操作(参见上面的Java文件):

    • 将其读取到InputStream:
    • 执行转换:

    在上面的示例中,我们只是将一个单元格的值作为字符串返回给Mule。但您也可以创建CSV类型的字符串,例如 a,b,c\nd,e,f

    %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
  •  0
  •   Maciej Czarnecki    6 年前

    是的,您可以将InputStream传递给Java模块方法调用,并使用ApachePOI(也可以读取xls和xlsx)进行流到csv的转换。