сегодня в 15:44
Здравствуйте!
Представляю пример простого консольного приложения на Java, которое считывает данные из БД и из файла *.xslx, а затем создает документ *.docx, заполняя при этом поля слияния (mergefield). В нем используются библиотеки Apache POI, docx4j и springframework.jdbc. В примере собрана воедино реализация нескольких часто возникающих в процессе автоматизации задач. Возможно, что он кому-то будет полезен.
О приложение
Что оно умеет:
Необходимость в данного рода приложении возникла, когда потребовалось вручную формировать некоторое количество однотипных документов для их дальнейшей печати и отправки почтой. Собрав воедино различные куски из других своих мелких наработок, появилось это приложение.
Выбор библиотеки Apache POI не стоял, так как уже реализовывал задачи с ее использованием. А вот docx4j применил из-за того, что в ней была возможность заполнять поля слияния в документах MS Word. Это мне и было нужно.
На входе мы имеем некий файл MS Excel, в котором имеется информация, идентифицирующая клиентов. Информация о клиентах не полная. Для извлечения дополнительных данных мы будем вынуждены обращаться в базу данных Oracle через jdbc. Затем приложение сформирует файл MS Word по каждому клиенту.
Представляю пример простого консольного приложения на Java, которое считывает данные из БД и из файла *.xslx, а затем создает документ *.docx, заполняя при этом поля слияния (mergefield). В нем используются библиотеки Apache POI, docx4j и springframework.jdbc. В примере собрана воедино реализация нескольких часто возникающих в процессе автоматизации задач. Возможно, что он кому-то будет полезен.
О приложение
Что оно умеет:
- Считывать данные из файла формата xslx
- Извлекать информации из БД (В данном случае используется Oracle)
- Формировать файлы формата docx на основе существующего фала, попутно добавлять значения в поля слияния
Необходимость в данного рода приложении возникла, когда потребовалось вручную формировать некоторое количество однотипных документов для их дальнейшей печати и отправки почтой. Собрав воедино различные куски из других своих мелких наработок, появилось это приложение.
Выбор библиотеки Apache POI не стоял, так как уже реализовывал задачи с ее использованием. А вот docx4j применил из-за того, что в ней была возможность заполнять поля слияния в документах MS Word. Это мне и было нужно.
На входе мы имеем некий файл MS Excel, в котором имеется информация, идентифицирующая клиентов. Информация о клиентах не полная. Для извлечения дополнительных данных мы будем вынуждены обращаться в базу данных Oracle через jdbc. Затем приложение сформирует файл MS Word по каждому клиенту.
Реализация
- Приложение создано с использованием maven. Для начала разберемся с нужными нам зависимостями. Вот что необходимо добавить в файл pom.xmlDependencies
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>2.5.6</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-dao</artifactId>
<version>2.0.6</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>2.5.6</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>2.5.6</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>2.5.6</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>ojdbc</groupId>
<artifactId>ojdbc</artifactId>
<version>14</version>
</dependency>
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j</artifactId>
<version>2.8.1</version>
</dependency>
- Рассмотрим класс App — главный класс приложения. В метоже main данного класса просто создается объект класса HelperWord и вызывается его метод createWord()Класс App
public class App
{
public static void main( String[] args )
{
HelperWord helper = new HelperWord();
helper.createWord();
}
} - В классе HelperWord мы получаем данные о клиенте, обрабатываем их и создаем файл MS Word.Класс HelperWord
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.exceptions.InvalidFormatException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
public class HelperWord {
// Объект класса MyDataManager для работы с данными
private MyDataManager dmg;
// Данные из фала *.xslx
private List<HashMap> clientsRows;
// Дополнительные данные из БД
private List<HashMap> additionalData;
// Инициирует создание файлов MS Word
public void createDocs() {
// Создаем объект класса MyDataManager для работы с данными
dmg = new MyDataManager();
try {
// Извлекаем данные из файла MS Excel
clientsRows = dmg.getDataBlock();
// <editor-fold defaultstate="collapsed" desc="Catch clauses">
} catch (FileNotFoundException ex) {
Logger.getLogger(HelperWord.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(HelperWord.class.getName()).log(Level.SEVERE, null, ex);
//</editor-fold>
}
// Создаем файл MS Word и заполняем его
addDataBlock();
}
// Создает файл MS Word и заполняет его
private void addDataBlock() {
int num = 0;
// Считываем информацию о каждом клменте
for (HashMap row : clientsRows) {
try {
num++;
// Извлекаем данные о существующем объекте MS Word
WordprocessingMLPackage wordMLPackage =
WordprocessingMLPackage
.load(new File("template.docx"));
// Создаем объект для вставки значений в поля слияния
List<Map<DataFieldName, String>> data =
new ArrayList<Map<DataFieldName, String>>();
// Получаем дополнительные данные о клиенте из базы
additionalData = dmg.getAddress(row.get("NAME").toString(),
row.get("DOCDATE").toString());
// Заполняем значения для полей слияния
Map<DataFieldName, String> map =
new HashMap<DataFieldName, String>();
map.put(new DataFieldName("NAME"), row.get("NAME").toString());
map.put(new DataFieldName("ADDRESS"),
additionalData.get(0).get("ADDRESS").toString());
data.add(map);
// Создаем новый объект MS Word на основе существующего и
// значений полей слияния
WordprocessingMLPackage output =
MailMerger.getConsolidatedResultCrude(
wordMLPackage, data);
// Сохраняем объект в файл
output.save(new File("T:\\VIPISKI_KK\\Письма\\"
+ num + ". " + row.get("NAME") + ".docx"));
// <editor-fold defaultstate="collapsed" desc="Catch clauses">
} catch (InvalidFormatException ex) {
Logger.getLogger(HelperWord.class.getName()).log(Level.SEVERE, null, ex);
} catch (Docx4JException ex) {
Logger.getLogger(HelperWord.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
Logger.getLogger(HelperWord.class.getName()).log(Level.SEVERE, null, ex);
} catch (FileNotFoundException ex) {
Logger.getLogger(HelperWord.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(HelperWord.class.getName()).log(Level.SEVERE, null, ex);
}
// </editor-fold>
}
}
}
Именно здесь мы заполняем поля слияния в документе, используя библиотеку docx4j. Пожалуй, внимание стоит обратить лишь на классы DataFieldName и MailMerger. Вроде бы, они оба должны присутствовать в библиотеке docx4j, однако в моей сборке их не оказалось. Поэтому они были добавлены в проект отдельно. Пару слов об этих классах- В классе DataFieldName есть поле name и переопределен метод equals. Это сделано для того, что мы сравнивали названия полей слияния в верхнем регистре
- Класс MailMerger как раз и осуществляет вставку значений в поля слияния документа. Код класса полностью позаимствован с официального сайта docx4j. Вот ссылка
- MyDataManager — класс для работы с данными. Он использует библиотеки Apache POI для чтения фала MS Excel и классы springframework.jdbc для работы с БД.Класс MyDataManager
import java.io.*;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import oracle.jdbc.pool.OracleDataSource;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
public class MyDataManager {
public NamedParameterJdbcTemplate namedPar;
private OracleDataSource getDataSource() throws SQLException {
// Создаем объект источника данных и заполняем значения параметров
OracleDataSource ods = new OracleDataSource();
ods.setDriverType("thin");
ods.setServerName("192.168.x.x");
ods.setPortNumber();
ods.setDatabaseName("SID");
ods.setUser("user");
ods.setPassword("password");
return ods;
}
//Получаем данные из MS Excel
public List<HashMap> getDataBlock()
throws FileNotFoundException, IOException {
ArrayList<HashMap> res = new ArrayList<HashMap>();
FileInputStream file = new FileInputStream(new File("clients.xlsx"));
XSSFWorkbook workbook = new XSSFWorkbook(file);
XSSFSheet sheet = workbook.getSheetAt(0);
Iterator<Row> rowIterator = sheet.iterator();
// Пропускаю первую строку. В моем случае в ней только заколовки
if(rowIterator.hasNext()) rowIterator.next();
//Пробегаемся по всем строкам
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
HashMap line = new HashMap();
// В моей структуре файла мне интересны только 1-ая и 4-ая строки
Cell cell = row.getCell(0);
line.put("NAME", cell.getStringCellValue());
cell = row.getCell(3);
line.put("DOCDATE", cell.getStringCellValue());
res.add(line);
}
file.close();
return res;
}
//Получаем данные из БД
public List<HashMap> getAddress(String name, String date)
throws SQLException, FileNotFoundException, IOException {
// Получаем источник данных
OracleDataSource ds = getDataSource();
// Считываем запрос
FileInputStream fins = new FileInputStream("query.txt");
BufferedReader br = new BufferedReader(
new InputStreamReader(fins, "UTF8"));
String query = "";
String line = "";
while ((line = br.readLine()) != null) {
query += "\n";
query += line;
}
// Вставляем значения параметров
namedPar = new NamedParameterJdbcTemplate(ds);
MapSqlParameterSource namedParameters = new MapSqlParameterSource();
namedParameters.addValue("NAME", name);
namedParameters.addValue("DOCDATE", date);
// Исполняем запрос и получае результат
List<HashMap> res = (List<HashMap>) namedPar.query(query,
namedParameters, new DataMapper());
try {
return res;
} finally {
ds.close();
}
}
}
Заключение
Вот собственно и все приложение. Конечно, многон в нем зашито в код (настройки соединения с базой, пути к файлам) и к тому же оно консольное. Можно добавить различные проверки и создать gui. Я этого не делал, так как задача была разовая. Все равно надеюсь, что пост будет кому-то полезен!
Спасибо за внимание!
Автоматизированное
продвижение сайтов
- 50% экономии на ссылках
- Запуск проекта за 10 минут
- Вывод и удержание в ТОП 10
Подробнее
Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.
This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.
Комментариев нет:
Отправить комментарий