Импорт Excel с помощью JXLS: можно ли указать лист по порядку, а не по имени?

Я использую 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, чтобы он просто читал первый лист и только первый лист, независимо от его имени? В гугле ничего не нашел, но если можно, дайте ссылку

Большое спасибо


person Steve    schedule 13.12.2012    source источник


Ответы (3)


Со страницы jxls:

Начиная с версии 1.0.2 jxls-reader поддерживает отображение листов по индексу. Это может быть удобно, если вы не знаете названия листов.

Просто используйте

<worksheet idx="0">

вместо

<worksheet name="sheetName">
person coberty    schedule 20.08.2013

Я связался с разработчиком. Он сказал, что этой функции пока нет. Он подумает о включении этого в будущий релиз.

В качестве обходного пути он предложил прочитать в книге с помощью POI API, чтобы узнать имя листа. Затем обновите конфигурацию XML в памяти с помощью правильного имени листа и передайте его в ReaderBuilder или создайте конфигурацию без XML, но с вызовами API.

HTH кто-то еще гуглил по этому вопросу.

person Steve    schedule 15.12.2012

Как указал Коберти, вы можете использовать

<worksheet idx="0"> 

Но для полноты: у меня была аналогичная проблема, но мне нужно было указать имя листа во время выполнения (пользователь выбирает из списка листов выбранного пользователем файла Excel, читая имена листов через Apache POI). Я сделал это, используя пример JXLS Reader с веб-сайта и немного изменив его:

Вместо:

  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);
   }

Теперь я могу использовать переменную sheetName в XML-конфигурации JXLS Reader:

   <worksheet name="${sheetName}">
person user1439628    schedule 03.03.2016