Самый простой способ сравнить два файла Excel в Java? - PullRequest
15 голосов
/ 15 мая 2009

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

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

Ответы [ 11 ]

12 голосов
/ 10 сентября 2012

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

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

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)

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

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

8 голосов
/ 15 мая 2009

Вот что я в итоге делал (с тяжелой работой, выполняемой 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);
  }
}

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

6 голосов
/ 15 мая 2009

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

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

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

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

Кстати: чтение всего файла для проверки его корректности обычно не считается модульным тестом. Это интеграционный тест ...

4 голосов
/ 05 августа 2015

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

Дамп в строку:

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

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

2 голосов
/ 20 мая 2016

Самый простой способ, который я найду, - это использовать Тику. Я использую это так:

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>
2 голосов
/ 15 мая 2009

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

http://javaxdelta.sourceforge.net/

0 голосов
/ 31 мая 2019

Для проверки только содержимого первых листов в Kotlin (легко может быть преобразовано в Java).

private fun checkEqualityExcelDocs(doc : XSSFWorkbook, doc1 : XSSFWorkbook) : Boolean{
        val mapOfCellDoc = doc.toList().first().toList().flatMap { row -> row.map { Pair(PivotExcelCreator.IndexInThePivotTable(it.rowIndex,it.columnIndex),it.stringCellValue) }}.toMap()
        val mapOfCellDoc1 = doc1.toList().first().toList().flatMap { row -> row.map { Pair(PivotExcelCreator.IndexInThePivotTable(it.rowIndex,it.columnIndex),it.stringCellValue) }}.toMap()
        if(mapOfCellDoc.size == mapOfCellDoc1.size){
            return mapOfCellDoc.entries.all { mapOfCellDoc1.containsKey(it.key) && mapOfCellDoc[it.key] == mapOfCellDoc1[it.key]}
        }
        return false
    }

data class IndexInThePivotTable(val row: Int, val col: Int)

и в вашем коде добавьте assert

    assertTrue(checkEqualityExcelDocs(expected, actual), "Docs aren't equal!")

, как вы можете видеть doc.toList().first() займет только первый лист документа, если вам нужно сравнить каждый лист или немного изменить код.

Также неплохо бы не учитывать "" пустые строковые ячейки, мне эта функциональность не нужна (также просто добавьте эту часть, если вам нужно).


также может быть полезна информация

//first doc I've got from outputstream such way
val out = ByteArrayOutputStream()
//some method which writes excel to outputstream
val firstDoc = XSSFWorkbook(ByteArrayInputStream(out.toByteArray()))

и второй документ из файла для сравнения с

val secondDoc = XSSFWorkbook(Test::class.java.getClassLoader().getResource("yourfile.xlsx").path)
0 голосов
/ 26 апреля 2010

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

  • Сравнение листов Excel как таблиц базы данных
  • Проверка всего текстового содержимого
  • Проверка текстового содержимого с некоторым форматированием
0 голосов
/ 15 мая 2009

Пожалуйста, посмотрите на сайт , чтобы сравнить двоичные файлы, http://www.velocityreviews.com/forums/t123770-re-java-code-for-determining-binary-file-equality.html

Tiger

0 голосов
/ 15 мая 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...