Java создание excel файла
Ранее мы рассматривали пример на тему Чтение данных из Excel. А сегодня узнаем, как можно сохранять данные в формате Excel. Для работы нам потребуются всё те же зависимости от Apache POI. Пример проекта на github прилагается.
Добавим необходимые зависимости в pom.xml.
<dependency><groupId> org.apache.poi </groupId>
<artifactId> poi </artifactId>
<version> 4.1.1 </version>
</dependency>
<dependency>
<groupId> org.apache.poi </groupId>
<artifactId> poi-ooxml </artifactId>
<version> 4.1.1 </version>
</dependency>
Предположим, у нас есть такая структура данных для хранения имени клиента и его даты рождения:
public class ClientInfo <
<>private final String name;
private final LocalDate birthDate;
// далее идут конструктор и геттеры для этих полей.
Теперь разберёмся, как создать файл Excel и записать туда данные. Причём в каждой строке Excel у нас будет не по 2, а по 3 ячейки. В третьей ячейке мы будем вычислять средствами Excel текущий возраст клиента.
Сначала создаём объект, представляющий книгу (файл) Excel с помощью класса XSSFWorkbook. Затем создаём лист в этой книге с помощью метода createSheet(). Затем первой строкой на лист добавляем заголовок, в котором будут указаны названия колонок в таблице (метод createHeader()). После этого построчно создаём ячейки с помощью метода createCells(). В конце создаём файловый поток вывода FileOutputStream, связанный с именем файла, который мы планируем создать. В конструкции try-with-resources сохраняем данные в этот файл (метод write()) и конце завершаем работу с книгой (метод close()).
public void write(String filename) throws IOException <var workbook = new XSSFWorkbook();
var sheet = createSheet(workbook);
createHeader(workbook, sheet);
createCells(workbook, sheet);
try ( var outputStream = new FileOutputStream(filename)) <
workbook.write(outputStream);
>
workbook.close();
>
Создание листа заключается в том, что мы создаём сам объект листа, а также задаём имя этого листа (отображается в Excel внизу листа). Для каждой колонки указываем её ширину в некоторых безразмерных единицах с помощью метода setColumnWidth().
private Sheet createSheet(XSSFWorkbook workbook) <var sheet = workbook.createSheet( "Клиенты" );
sheet.setColumnWidth( 0 , 4000 );
sheet.setColumnWidth( 1 , 6000 );
sheet.setColumnWidth( 2 , 4000 );
return sheet;
>
Создаём заголовок и задаём стиль для него (метод createCellStyle()). В данном примере мы для фона заголовка задаём серый цвет. Также зададим шрифт для заголовка, отличный от стандартного. В данном случае мы выбираем жирный шрифт Arial размером в 14 пунктов (методы createFont(), setFontName(), setFontHeightInPoints(), setBold()).
private void createHeader(XSSFWorkbook workbook, Sheet sheet) <
var header = sheet.createRow( 0 );
var headerStyle = workbook.createCellStyle();
headerStyle.setFillForegroundColor(IndexedColors. GREY_25_PERCENT .getIndex());
headerStyle.setFillPattern(FillPatternType. SOLID_FOREGROUND );
var font = workbook.createFont();
font.setFontName( "Arial" );
font.setFontHeightInPoints(( short ) 14 );
font.setBold( true );
headerStyle.setFont(font);
var headerCell = header.createCell( 0 );
headerCell.setCellValue( "Имя" );
headerCell.setCellStyle(headerStyle);
headerCell = header.createCell( 1 );
headerCell.setCellValue( "Дата рождения" );
headerCell.setCellStyle(headerStyle);
headerCell = header.createCell( 2 );
headerCell.setCellValue( "Возраст" );
headerCell.setCellStyle(headerStyle);
>
Затем создаём три ячейки (createCell() c указанием номера ячейки), из которых будет состоять наш заголовок. Текст для ячейки задаём с помощью метода setCellValue(), а ранее созданный стиль - с помощью setCellStyle().
Теперь перейдём к созданию ячеек с данными.
private void createCells(XSSFWorkbook workbook, Sheet sheet) <
var style = workbook.createCellStyle();
style.setWrapText( true );
var createHelper = workbook.getCreationHelper();
style.setDataFormat(createHelper.createDataFormat().getFormat( "dd.mm.yyyy" ));
sheet.setDefaultColumnStyle( 1 , style);
for ( var i = 0 ; i < CLIENTS .size(); i++) var client = CLIENTS .get(i);
var row = sheet.createRow(i + 1 );
var cell = row.createCell( 0 );
cell.setCellValue(client.getName());
cell = row.createCell( 1 );
cell.setCellValue(client.getBirthDate());
cell = row.createCell( 2 );
cell.setCellFormula(String.format( "TEXT(DATEDIF(B%s,NOW(),\"Y\"), \"0\")" , i + 2 ));
>
>
Создаём стиль для ячеек (метод createCellStyle()). Также для этого стиля определяем формат для ячеек с датами. В этом нам поможет вспомогательный класс, возвращаемый методом getCreationHelper(). Дни рождения клиентов будем отображать в формате dd.mm.yyyy. Теперь мы можем задать стиль по умолчанию для всей колонки. Дни рождения содержатся во второй колонке, поэтому вызываем метод setDefaultColumnStyle() с индексом 1. Важно задать стиль по умолчанию до начала заполнения самих ячеек данными. Мы могли бы также для задания стиля ячеек использовать и setCellStyle(), рассмотренный выше, но при большом количестве ячеек можно израсходовать лимит стилей, который допускает Excel.
Затем в цикле проходимся по списку, содержащему объекты ClientInfo. На каждой итерации создаём новую строку с указанием её порядкового номера, прибавляя 1, т.к. 0 строка - это заголовок таблицы. Обычные значение указываем с помощью метода setCellValue(). Третья колонка нашей таблицы будет содержать текущий возраст клиентов, динамически вычисляемый средствами Excel. Поэтому мы задаём не фиксированное значение, а формулу с помощью метода setCellFormula(). В формуле мы ссылаемся на колонку B, т.е. туда, где содержится дата рождения клиента. Затем в формуле вычисляется разница между текущей датой и датой рождения клиента в годах. После этого преобразуем полученное значение в текст для удобства отображения.
Как видите, создавать таблицы и ячейки Excel совсем несложно. При необходимости мы можем создавать свои стили для отображения данных: менять шрифт, его размер, цвет, стиль и фон. В итоге мы получим файл в формате xlsx.
Из этой статьи вы сможете узнать о записи и чтении данных из Excel файлов в Java (будет рассмотрен как XLS , так и XLSX формат). Мы будем использовать библиотеку Apache POI и сосредоточимся на работе с типами String и Date , работа с последним происходит достаточно хитро. Напомню, что работу с числами мы уже рассмотрели в другой статье.
Библиотеку poi-XX.jar вы можете использовать для всех старых ( xls , doc , ppt ) файлов Microsoft Office, для новых ( xlsx , docx , pptx ) вам понадобится poi-ooxml-XX.jar . Очень важно понимать, что к чему относится, т.к. используемые классы тоже разные — для старых расширений это HSSFWorkbook , а для новых — XSSFWorkbook .
Подготовка: загрузка библиотек и зависимостей
Конечно, существует достаточно много открытых библиотек, которые позволяют работать с Excel файлами в Java, например, JXL, но мы будем использовать имеющую самый обширный API и самую популярную — Apache POI. Чтобы её использовать, вам нужно скачать jar файлы и добавить их через Eclipse вручную, или вы можете предоставить это Maven.
Во втором случае вам нужно просто добавить следующие две зависимости:
Самое удобное в Maven — что он загрузит не только указанные poi.jar и poi-ooxml.jar , но и все jar файлы, которые используются внутри, то есть xmlbeans-2.6.0.jar , stax-api-1.0.1.jar , poi-ooxml-schemas-3.12.jar и commons-codec-1.9.jar .
4–5 декабря, Онлайн, Беcплатно
Запись
В этом примере мы запишем в xls файл следующие данные: в первую ячейку — строку с именем, а во вторую — дату рождения. Вот пошаговая инструкция:
- Создаём объект HSSFWorkBook ;
- Создаём лист, используя на объекте, созданном в предыдущем шаге, createSheet() ;
- Создаём на листе строку, используя createRow() ;
- Создаём в строке ячейку — createCell() ;
- Задаём значение ячейки через setCellValue();
- Записываем workbook в File через FileOutputStream ;
- Закрываем workbook , вызывая close() .
Для записи строк или чисел этого вполне достаточно, но чтобы записать дату, нам понадобится сделать ещё кое-что:
- Создать DateFormat ;
- Создать CellStyle ;
- Записать DateFormat в CellStyle ;
- Записать CellStyle в ячейку;
- Теперь в эту ячейку можно записать объект Date через всё тот же setCellValue ;
- Чтобы дата поместилась в ячейку, нам нужно добавить столбцу свойство автоматически менять размер: sheet.autoSizeColumn(1) .
Всё вместе это будет выглядеть так:
Чтение
Теперь мы считаем из только что созданного файла то, что мы туда записали.
- Для начала создадим HSSFWorkBook , передав в конструктор FileInputStream ;
- Получаем лист, передавая в getSheet() его номер или название;
- Получаем строку, используя getRow() ;
- Получаем ячейку, используя getCell() ;
- Узнаём тип ячейки, используя на ней getCellType() ;
- В зависимости от типа ячейки, читаем её значения, используя getStringCellValue() , getNumericCellValue() или getDateCellValue() ;
- Закрываем workbook используя close() .
Напомню, что дату Excel хранит как числа, т.е. тип ячейки всё равно будет CELL_TYPE_NUMERIC .
Собственно возникла проблема — обработать данные из таблицы и на их основе получить другую таблицу.
Для чтения книги из файла можно применить следующий код:
Метод возвращает объект класса HSSFWorkbook если все удачно и null в другом случае.
Для сохранения изменений можно применить следующий метод:
Метод записывает книгу wb в файл fileName
- По имени
HSSFSheet sheet= wb.getSheet("Лист 3") - По номеру (нумерация начинается с 0)
HSSFSheet sheet= wb.getSheet(0) - Создание нового листа
HSSFSheet sheet= wb.createSheet(["имя листа"])
- По индексу (индексация начинается с 0)
HSSFRow row = sheet.getRow(index) - Через итератор
- Создание новой строки
HSSFRow row=sheet.createRow(0);
- По индексу ячейки (индексация начинается с 0)
HSSFCell cell = row.getCell(0); - Через итератор
- Создание новой ячейки
HSSFCell cell = row.createCell(0);
- Логическое значение
boolean b = cell.getBooleanCellValue();
cell.setCellValue(b); - Дата
Date date = cell.getDateCellValue();
cell.setCellValue(date); - Числовое значение
double d = cell.getNumericCellValue();
cell.setCellValue(d); - Строковое значение
String str = cell.getRichStringCellValue().getString();
cell.setCellValue(new HSSFRichTextString(str)); - Формула
String formula = cell.getCellFormula();
cell.setCellFormula(formula);
Этих знаний достаточно чтобы обрабатывать простые таблицы.
Библиотека также предоставляет богатые возможности по форматированию ячеек, по их слиянию, заморозке и т.д.
Подробное описание функций можно найти на их сайте.
Данный способ прежде всего ценен тем, что не требует установки самого офиса и пакета PIA.
Я хочу создать файл Excel и записывать данные так же, как писать текстовый файл с помощью Java. Я попытался изменить расширение файла с .txt на .xls . Но я хочу жирные буквы в файле Excel. Как я могу это сделать?
Я пробовал использовать JXL API, но каждый раз, когда мне нужно создать метку, я не хочу добавлять метку. Не можете редактировать строку и столбец таблицы?
Ответы
Вы можете использовать Apache POI для создания собственных двоичных файлов xls.
Или вы можете использовать JExcelApi, еще одну и несколько облегченную, насколько я помню, библиотеку Java для Excel.
Справедливое предупреждение о генерации Excel в Apache POI . (я знаю, что это старый пост, но он важен на случай, если кто-то снова найдет его, как только что сделал я)
У него была проблема с утечкой памяти, которая предположительно была решена к 2006 году, но с которой люди все еще сталкивались совсем недавно. Если вы хотите автоматизировать создание большого количества файлов Excel (например, если вы хотите создать один большой файл, большое количество маленьких файлов или и то, и другое), я бы рекомендовал использовать другой API. Либо это, либо увеличение размера стека JVM до нелепых пропорций, и, возможно, изучение интернирующих строк, если вы знаете, что на самом деле не будете работать со многими разными строками (хотя, конечно, интернированные строки означают, что если у вас есть большое количество разные строки, у вас будет совершенно другая проблема с памятью программы. Поэтому подумайте об этом, прежде чем идти по этому пути).
Плоские файлы не позволяют предоставлять метаинформацию.
Я бы посоветовал написать HTML-таблицу, содержащую нужную вам информацию, и позволить Excel читать ее вместо этого. Затем вы можете использовать теги <b>, чтобы делать то, о чем вы просите.
Я создал API, чтобы упростить создание файла Excel.
Просто установите необходимые значения при создании экземпляра, затем вызовите execute (), он будет создан на основе желаемого выходного каталога.
Но прежде чем использовать его, у вас должен быть шаблон Excel, который будет использоваться в качестве шаблона для вновь созданного файла Excel.
Кроме того, вам понадобится Apache POI в пути к классу вашего проекта.
Изменение расширения файла не каким - либо образом изменить его содержимое. Расширение - это просто ярлык.
Если вы хотите работать с электронными таблицами Excel с помощью Java, прочтите библиотеку Apache POI .
Я также использовал JXLS : он получает данные как карту и шаблон EXCEL с правильным синтаксисом и возвращает правильно заполненный файл. Данные в каждой ячейке должны быть JavaBean-компонентом с общедоступной видимостью.
Не работает, если вам нужно вставить данные более чем на 1 лист: в этом случае я использовал POI .
Чтобы создать электронную таблицу и отформатировать ячейку с помощью POI , см. Пример « Работа со шрифтами» и используйте:
POI работает очень хорошо. Есть некоторые вещи, которые вы не можете делать (например, создавать макросы VBA), но он будет читать / писать таблицы с макросами, поэтому вы можете создать подходящий шаблонный лист, прочитать его и манипулировать им с помощью POI, а затем записать его.
Я создал API "generator-excel" для создания файла Excel ниже зависимости:
Эта библиотека может настраивать стили, функции, диаграммы, сводную таблицу и т. Д. С помощью серии аннотаций.
Вы можете писать строки, получая данные из источника данных через запрос с параметрами или без них.
Ниже пример для разработки
- Я создал 2 класса, которые представляют строку таблицы.
- Я создал 2 класса, которые представляют листы.
- Классный тест, в тестовой функции есть еще листы
- Приложение yaml
ниже ссылка проекта на github:
Связанные вопросы
Как читать и писать файл Excel
Как я могу читать числовые строки в ячейках Excel как строку (а не числа)?
Читайте также: