【问题标题】:Importing Excel With JXLS: is it possible to specify sheet by order rather than name?使用 JXLS 导入 Excel:是否可以按顺序而不是名称指定工作表?
【发布时间】:2012-12-13 22:43:37
【问题描述】:

我正在使用 JXLS XLSReader 读取 Microsoft Excel 文件。

这是我的配置文件的副本:

<?xml version="1.0" encoding="ISO-8859-1"?>
<workbook>
  <worksheet name="staff_acme">
    <loop startRow="1" endRow="1" items="VECIDataHolder" var="vdh" varType="gov.noaa.nsd.model.data.dataholders.VECIDataHolder">
      <section startRow="1" endRow="1">
        <mapping row="1" col="0">vdh.person_id</mapping>
        <mapping row="1" col="1">vdh.fullname</mapping>
        <mapping row="1" col="2">vdh.noaa_email_address</mapping>
        <mapping row="1" col="3">vdh.emergency_email_address</mapping>
        <mapping row="1" col="4">vdh.emergency_cell</mapping>
        <mapping row="1" col="5">vdh.emergency_sms</mapping>
      </section>
      <loopbreakcondition>
        <rowcheck offset="0">
          <cellcheck offset="0"/>
        </rowcheck>
      </loopbreakcondition>
    </loop>
  </worksheet>
</workbook>

我的用户一直在更改工作表的名称,这让 JXLS 错过了它。

有没有办法告诉 JXLS 只阅读第一张纸,并且只阅读第一张纸,不管它的名字是什么?我在 Google 上找不到任何内容,但如果您可以,请随时发布链接

非常感谢

【问题讨论】:

    标签: java excel import jxls


    【解决方案1】:

    来自 jxls 页面:

    从 1.0.2 版开始,jxls-reader 支持按索引映射工作表。如果您不知道工作表的名称,这会很方便。

    随便用

    <worksheet idx="0">
    

    而不是

    <worksheet name="sheetName">
    

    【讨论】:

      【解决方案2】:

      我联系了开发商。他说这个功能还不存在。他会考虑将其放入未来的版本中。

      作为一种解决方法,他建议使用 POI API 阅读工作簿以找出工作表名称。然后使用适当的工作表名称更新内存中的 XML 配置,并将其提供给 ReaderBuilder 或构建没有 XML 但使用 API 调用的配置。

      其他人在谷歌上搜索这个问题。

      【讨论】:

        【解决方案3】:

        正如 coberty 所指出的,您可以使用

        <worksheet idx="0"> 
        

        但为了完整起见:我遇到了类似的问题,但我需要在运行时指定工作表名称(用户从用户选择的 Excel 文件的工作表列表中选择,通过 Apache POI 读取工作表名称)。我通过使用网站上的 JXLS 阅读器示例并稍作更改来完成此操作:

        代替:

          final XLSReader reader = ReaderBuilder.buildFromXML(xmlInputStream);
        

        我使用这个方法的副本,使用 Apache Digester setSubstitutor 稍作改动(不幸的是,ReaderBuilder 不允许将替代器作为参数传递......):

          final XLSReader reader = buildFromXML(xmlInputStream, sheetName);
        
          ...
        
        
          public static XLSReader buildFromXML(final InputStream xmlStream, final String sheetName)
                 throws IOException, SAXException {
        
              final Digester digester = new Digester();
        
              // hier geschieht die Substituierung des Tabellenblattnamens -
              // der Rest der Methode entspricht dem Original
              substituteSheetName(sheetName, digester);
        
              digester.setValidating(false);
              digester.addObjectCreate("workbook", "org.jxls.reader.XLSReaderImpl");
              digester.addObjectCreate("workbook/worksheet", "org.jxls.reader.XLSSheetReaderImpl");
              digester.addSetProperties("workbook/worksheet", "name", "sheetName");
              digester.addSetProperties("workbook/worksheet", "idx", "sheetIdx");
              digester.addSetNext("workbook/worksheet", "addSheetReader");
              digester.addObjectCreate("*/loop", "org.jxls.reader.XLSForEachBlockReaderImpl");
              digester.addSetProperties("*/loop");
              digester.addSetNext("*/loop", "addBlockReader");
              digester.addObjectCreate("*/section", "org.jxls.reader.SimpleBlockReaderImpl");
              digester.addSetProperties("*/section");
              digester.addSetNext("*/section", "addBlockReader");
              digester.addObjectCreate("*/mapping", "org.jxls.reader.BeanCellMapping");
              digester.addSetProperties("*/mapping");
              digester.addCallMethod("*/mapping", "setFullPropertyName", 1);
              digester.addCallParam("*/mapping", 0);
              digester.addSetNext("*/mapping", "addMapping");
              digester.addObjectCreate("*/loop/loopbreakcondition", "org.jxls.reader.SimpleSectionCheck");
              digester.addSetNext("*/loop/loopbreakcondition", "setLoopBreakCondition");
              digester.addObjectCreate("*/loopbreakcondition/rowcheck", "org.jxls.reader.OffsetRowCheckImpl");
              digester.addSetProperties("*/loopbreakcondition/rowcheck");
              digester.addSetNext("*/loopbreakcondition/rowcheck", "addRowCheck");
              digester.addObjectCreate("*/rowcheck/cellcheck", "org.jxls.reader.OffsetCellCheckImpl");
              digester.addSetProperties("*/rowcheck/cellcheck");
              digester.addCallMethod("*/rowcheck/cellcheck", "setValue", 1);
              digester.addCallParam("*/rowcheck/cellcheck", 0);
              digester.addSetNext("*/rowcheck/cellcheck", "addCellCheck");
              return (XLSReader) digester.parse(xmlStream);
           }
        
           private static void substituteSheetName(final String sheetName, final Digester digester) {
              // set up the variables the input xml can reference
              final Map<String, Object> vars = new HashMap<String, Object>();
              vars.put("sheetName", sheetName);
        
              // map ${varname} to the entries in the var map
              final MultiVariableExpander expander = new MultiVariableExpander();
              expander.addSource("$", vars);
        
              // allow expansion in both xml attributes and element text
              final Substitutor substitutor = new VariableSubstitutor(expander);
        
              digester.setSubstitutor(substitutor);
           }
        

        现在我可以在 JXLS 阅读器 XML 配置中使用变量 sheetName:

           <worksheet name="${sheetName}">
        

        【讨论】:

          猜你喜欢
          • 2019-09-27
          • 1970-01-01
          • 2014-03-23
          • 2017-12-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-12
          相关资源
          最近更新 更多