Самый простой способ сравнить два файла Excel в Java?

Я пишу тест JUnit для некоторого кода, который создает файл Excel (который является двоичным). У меня есть другой файл Excel, содержащий мой ожидаемый результат. Какой самый простой способ сравнить фактический файл с ожидаемым файлом?

Конечно, я мог написать код сам, но мне было интересно, существует ли существующий метод в доверенной сторонней библиотеке (например, Spring или Apache Commons), которая уже делает это.

Ответ 1

Вот что я в итоге сделал (с тяжелым подъемом делал DBUnit):

/**
 * Compares the data in the two Excel files represented by the given input
 * streams, closing them on completion
 * 
 * @param expected can't be <code>null</code>
 * @param actual can't be <code>null</code>
 * @throws Exception
 */
private void compareExcelFiles(InputStream expected, InputStream actual)
  throws Exception
{
  try {
    Assertion.assertEquals(new XlsDataSet(expected), new XlsDataSet(actual));
  }
  finally {
    IOUtils.closeQuietly(expected);
    IOUtils.closeQuietly(actual);
  }
}

Это сравнивает данные в двух файлах, без риска ложных негативов от любых нерелевантных метаданных, которые могут быть разными. Надеюсь, это поможет кому-то.

Ответ 2

Возможно, вы захотите использовать мой проект simple-excel, который предоставляет кучу совпадений Hamcrest для выполнения этой работы.

Когда вы делаете что-то вроде следующего,

assertThat(actual, WorkbookMatcher.sameWorkbook(expected));

Вы увидите, например,

java.lang.AssertionError:
Expected: entire workbook to be equal
     but: cell at "C14" contained <"bananas"> expected <nothing>,
          cell at "C15" contained <"1,850,000 EUR"> expected <"1,850,000.00 EUR">,
          cell at "D16" contained <nothing> expected <"Tue Sep 04 06:30:00">
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)

Таким образом, вы можете запускать его из ваших автоматизированных тестов и получать значимые отзывы во время разработки.

Подробнее об этом читайте в этой статье на моем сайте

Ответ 3

Простое сравнение файлов можно легко выполнить с помощью некоторых контрольных сумм (например, MD5) или просто для чтения обоих файлов.

Однако, поскольку файлы Excel содержат множество метаданных, файлы, вероятно, никогда не будут идентичными байтами для байта, как указал Джеймс Берджес. Поэтому вам понадобится другое сравнение для вашего теста.

Я бы рекомендовал каким-то образом создать "каноническую" форму из файла Excel, то есть прочитать сгенерированный файл Excel и преобразовать его в более простой формат (CSV или что-то подобное), который сохранит только информацию, которую вы хотите проверить. Затем вы можете использовать "каноническую форму" для сравнения с вашим ожидаемым результатом (также в канонической форме, конечно).

Apache POI может быть полезна для чтения файла.

BTW: Чтение всего файла, чтобы проверить его правильность, обычно не будет выглядеть как Unit test. Это интеграционный тест...

Ответ 4

Мне нужно было сделать что-то подобное и уже использовал Apache POI library в моем проекте для создания файлов Excel. Поэтому я решил использовать включенный ExcelExtractor интерфейс для экспорта обеих книг в виде строки текста и утверждал, что строки равны. Существуют реализации для HSSF для .xls, а также XSSF для .xlsx.

Дамп к строке:

XSSFWorkbook xssfWorkbookA = ...;
String workbookA = new XSSFExcelExtractor(xssfWorkbookA).getText();

В ExcelExtractor есть несколько вариантов того, что все должно быть включено в дамп строк. Я обнаружил, что он имеет полезные значения по умолчанию, включая имена листов. Кроме того, он включает текстовое содержимое ячеек.

Ответ 5

Вы можете использовать javaxdelta для проверки того, совпадают ли эти два файла. Это доступно здесь:

http://javaxdelta.sourceforge.net/

Ответ 6

Самый простой способ найти Тику. Я использую его следующим образом:

private void compareXlsx(File expected, File result) throws IOException, TikaException {
     Tika tika = new Tika();
     String expectedText = tika.parseToString(expected);
     String resultText = tika.parseToString(result);
     assertEquals(expectedText, resultText);
}


<dependency>
    <groupId>org.apache.tika</groupId>
    <artifactId>tika-parsers</artifactId>
    <version>1.13</version>
    <scope>test</scope>
</dependency>

Ответ 7

Только что нашел что-то в commons-io FileUtils. Спасибо за другие ответы.

Ответ 9

Вы можете использовать Beyond Compare 3, который можно запустить из командной строки и поддерживает различные способы сравнения файлов Excel, в том числе:

  • Сравнение таблиц Excel как таблиц базы данных
  • Проверка всего текстового содержимого
  • Проверка текстового содержимого с помощью некоторых форматов

Ответ 10

Может быть... сравнить MD5 дайджестов каждого файла? Я уверен, что есть много способов сделать это. Вы можете просто открыть оба файла и сравнить каждый байт.

EDIT: Джеймс заявил, что формат XLS может иметь различия в метаданных. Возможно, вы должны использовать тот же интерфейс, который вы использовали для генерации файлов xls, чтобы их открыть и сравнить значения из ячейки в ячейку?