Поиск по этому блогу

вторник, 28 мая 2013 г.

Apache POI + Google App Engine + MS Excel generate files and send to user

В проекте понадобилось разработать метод, который собирал бы пользователей из базы и формировал файл Microsoft Excel и посылал его пользователю. Так как система работает на Google App Engine, то возникли некоторые трудности при отправке сформированного excel файла, так как на GAE не поддерживаются некоторые классы из java.io. Для формирования excel-файла был выбран фреймвор Apache POI. В этом посте я хочу написать о том, как написать REST-метод, который будет, используя библиотеку Apache POI, формировать excel-файл и отправлять его пользователю.

Apache POI 


Apache POI - это фреймворк в который входят Java-библиотеки для чтения и записи электронных таблиц Excel. Более подробную информацию можно найти на официальном сайте http://poi.apache.org/
А maven-зависимости для проекта можно найти здесь http://mvnrepository.com/artifact/org.apache.poi

Последня версия на момент написания статьи это 3.9

Для подключения фреймворка Apache POI необходимо в файле проекта pom.xml добавить следующие зависимости.
Отрывок файла pom.xml
<!-- For excel files -->
  <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>

REST-метод для отправки excel-файла пользователю


В аннтоции @Produces указываем, что метод будет посылать  клиенту
@Produces({ MediaType.APPLICATION_OCTET_STREAM })

Это означает, что мы посылаем на клиент массив байтов.
Все возможные значения, которые можно указывать в качестве типа того, что серверный метод может отправлять клиенту можно посмотреть тут
http://docs.oracle.com/javaee/6/api/javax/ws/rs/core/MediaType.html

Создаем excel документ (workbook)
Workbook workbook = new XSSFWorkbook();

Создаем таблицу (sheet) внутри excel документа
Sheet sheet = workbook.createSheet("sample sheet");

Создаем строку для каждого пользователя
for (int i = 0; i <= allUsers.size(); i++) {
 
 Row row = sheet.createRow(i);

Создаем ячейки в строке
for (int j = 0; j < 6; j++) {
 
 Cell cell = row.createCell(j);

Создаем заголовки столбцов
if (i == 0) {
 
 if (j == 0) {
  cell.setCellValue("Id");
 } else if (j == 1) {
  cell.setCellValue("Полное имя");
 } else if (j == 2) {
  cell.setCellValue("E-mail");
 } else if (j == 3) {
  cell.setCellValue("Контактный телефон");
 } else if (j == 4) {
  cell.setCellValue("Тип");
 } else if (j == 5) {
  cell.setCellValue("Дата последней активности");
 }
 
}

Заполняем ячейки таблицы информацией
if (j == 0) {
 cell.setCellValue(String.valueOf(allUsers.get(i - 1).getId()));
} else if (j == 1) {
 cell.setCellValue(allUsers.get(i - 1).getFullName());
} else if (j == 2) {
 cell.setCellValue(allUsers.get(i - 1).getUserEmail());
} else if (j == 3) {
 cell.setCellValue(allUsers.get(i - 1).getContactPhone());
} else if (j == 4) {
 
 if (allUsers.get(i - 1).getFreeTransport() && 
            allUsers.get(i - 1).getSendCargo()) {
 
  cell.setCellValue("Водитель/Отправитель");
 
        } else if (allUsers.get(i - 1).getFreeTransport() && 
            !allUsers.get(i - 1).getSendCargo()) {
 
  cell.setCellValue("Водитель");
 
 } else if (!allUsers.get(i - 1).getFreeTransport() && 
            allUsers.get(i - 1).getSendCargo()) {
 
  cell.setCellValue("Отправитель");
 
 }
 
} else if (j == 5) {
 
 if (allUsers.get(i - 1).getLastActivityDate() != null) {
  cell.setCellValue(DateUtils.getFormattedDate(
                    allUsers.get(i - 1).getLastActivityDate()));
 } else {
  cell.setCellValue(" -");
 }
}

Создаем байтовый выходной поток
ByteArrayOutputStream out = new ByteArrayOutputStream();

Помещаем в этот поток созданный excel документ
workbook.write(out);

Преобразуем байтовый выходной поток в массив байтов и отправляем его пользователю
return Response.ok(out.toByteArray()).build();

Код REST-метода полностью

@GET
@Path("/getAllUsers")
@Produces({ MediaType.APPLICATION_OCTET_STREAM })
public Response getAllUsers(@QueryParam("date") String date)
  throws IOException {
 
  List<UserDTO> allUsers = userManager.getAllUsers(date);
 
  Workbook workbook = new XSSFWorkbook();
  Sheet sheet = workbook.createSheet("sample sheet");
 
  for (int i = 0; i <= allUsers.size(); i++) {
 
 Row row = sheet.createRow(i);
 
 for (int j = 0; j < 6; j++) {
 
   Cell cell = row.createCell(j);
 
   if (i == 0) {
 
     if (j == 0) {
   cell.setCellValue("Id");
  } else if (j == 1) {
   cell.setCellValue("Полное имя");
  } else if (j == 2) {
   cell.setCellValue("E-mail");
  } else if (j == 3) {
   cell.setCellValue("Контактный телефон");
  } else if (j == 4) {
   cell.setCellValue("Тип");
  } else if (j == 5) {
   cell.setCellValue("Дата последней активности");
  }
 
   } else {
 
     if (j == 0) {
    cell.setCellValue(String
      .valueOf(allUsers.get(i - 1)
   .getId()));
  } else if (j == 1) {
    cell.setCellValue(allUsers.get(i - 1)
      .getFullName());
  } else if (j == 2) {
    cell.setCellValue(allUsers.get(i - 1)
      .getUserEmail());
  } else if (j == 3) {
    cell.setCellValue(allUsers.get(i - 1)
    .getContactPhone());
  } else if (j == 4) {
 
    if (allUsers.get(i - 1).getFreeTransport()
      && allUsers.get(i - 1).getSendCargo()) {
 
     cell.setCellValue("Водитель/Отправитель");
 
    } else if (allUsers.get(i - 1).getFreeTransport()
      && !allUsers.get(i - 1).getSendCargo()) {
 
     cell.setCellValue("Водитель");
 
    } else if (!allUsers.get(i - 1).getFreeTransport()
      && allUsers.get(i - 1).getSendCargo()) {
 
     cell.setCellValue("Отправитель");
 
    }
 
  } else if (j == 5) {
 
    if (allUsers.get(i - 1).getLastActivityDate() != null) {
      cell.setCellValue(DateUtils
       .getFormattedDate(allUsers.get(i - 1)
       .getLastActivityDate()));
    } else {
        cell.setCellValue(" -");
    }
 
   }
 
  }
 
  }
 
  }
 
  ByteArrayOutputStream out = new ByteArrayOutputStream();
  workbook.write(out);
 
  return Response.ok(out.toByteArray()).build();
 
}

Комментариев нет:

Отправить комментарий