<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.6.5</version>
</dependency>
/**
* Экспортируйте информацию о клиентах CRM
*
* @param list1 Список 1
* @param list2 Список 2
* @param dataMap карта данных
* @param xlsxName Имя файла
*/
public static void exportCrmUserInfoList(String path, String xlsxName, List<?> list1, List<?> list2, Map<Object, Object> dataMap) throws IOException {
//TODO В будущем оно будет изменено на динамическое приобретение.
String templateFileName = "/Users/xguo/Desktop/template2.xlsx";
String fileName = path + "/" + xlsxName + ".xlsx";
//Получаем экземпляр ExcelWriter
ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
//Заполняем соответствующую переменную
excelWriter.fill(dataMap, writeSheet);
//заполняем список
excelWriter.fill(new FillWrapper("data1",list1),fillConfig, writeSheet);
excelWriter.fill(new FillWrapper("data2",list2), fillConfig,writeSheet);
//Закрываем поток
excelWriter.finish();
}
Путь к шаблону можно разместить в ресурсах проекта или настроить через центр конфигурации nacos, что более гибко. Для удобства тестирования он прописан в коде.
/**
* Сжатый список файлов
*
* @param zipOutName путь вывода zip-файла
* @param fileNameList список путей к файлам
* @throws IOException исключение ввода-вывода
* @throws ExecutionException Исключение выполнения
* @throws InterruptedException Исключение прерывания
*/
public static void compressFileList(String zipOutName, List<String> fileNameList) throws IOException, ExecutionException, InterruptedException {
ThreadFactory factory = new ThreadFactoryBuilder().setNamePrefix("compressFileList-pool-").build();
ExecutorService executor = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(20), factory);
ParallelScatterZipCreator parallelScatterZipCreator = new ParallelScatterZipCreator(executor);
OutputStream outputStream = new FileOutputStream(zipOutName);
ZipArchiveOutputStream zipArchiveOutputStream = new ZipArchiveOutputStream(outputStream);
zipArchiveOutputStream.setEncoding("UTF-8");
for (String fileName : fileNameList) {
File inFile = new File(fileName);
final InputStreamSupplier inputStreamSupplier = () -> {
try {
return new FileInputStream(inFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
return new NullInputStream(0);
}
};
ZipArchiveEntry zipArchiveEntry = new ZipArchiveEntry(inFile.getName());
zipArchiveEntry.setMethod(ZipArchiveEntry.DEFLATED);
zipArchiveEntry.setSize(inFile.length());
zipArchiveEntry.setUnixMode(UnixStat.FILE_FLAG | 436);
parallelScatterZipCreator.addArchiveEntry(zipArchiveEntry, inputStreamSupplier);
}
parallelScatterZipCreator.writeTo(zipArchiveOutputStream);
zipArchiveOutputStream.close();
outputStream.close();
log.info("ParallelCompressUtil->ParallelCompressUtil-> info:{}", JSONObject.toJSONString(parallelScatterZipCreator.getStatisticsMessage()));
}
/**
* Выходной файл передается во внешний интерфейс для загрузки.
*
* @param filePath путь к файлу
* @param response ответ
*/
public static void exportFileStream(String filePath, HttpServletResponse response) {
File file = new File(filePath);
if (!file.exists()) {
//Файл не существует, подсказка 404 - Запрошенный ресурс (веб-страница и т. д.) не существует.
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
}
try (FileInputStream is = new FileInputStream(file); OutputStream os = response.getOutputStream()) {
response.setCharacterEncoding(CharEncoding.UTF_8);
response.addHeader("Content-Disposition", "attachment;filename=" + file.getName().getBytes());
response.addHeader("Content-Length", "" + file.length());
response.setContentType("application/x-zip-compressed");
os.write(IoUtil.readBytes(is));
} catch (IOException e) {
log.error("Передача файла не удалась: {}", e.getMessage());
}
}
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* Объект просмотра экспорта информации о пользователе crm
*
* @author xGuo
* @date 2022/06/28
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("Объект просмотра экспорта информации о пользователе crm")
public class CrmUserInfoExportVo {
private static final long serialVersionUID = 1L;
@ApiModelProperty("Счет фонда клиента")
private String account;
@ApiModelProperty("Номер мобильного телефона клиента")
private String phone;
@ApiModelProperty("Контактный адрес")
private String address;
@ApiModelProperty("Номер удостоверения личности")
private String idCard;
@ApiModelProperty("Срок действия удостоверения личности")
private String idCardValidTime;
@ApiModelProperty("серийный номер")
private String id;
@ApiModelProperty("Состояние контракта")
private String state;
@ApiModelProperty("Срок действия контракта")
private String contractValidTime;
}
Соответствует Диаграмме шаблонанаОсновная информация о клиенте Информация о контракте переменная
import lombok.Data;
import java.util.Date;
/**
* объект заполнения списка
*
* @author xGuo
* @date 2022/06/28
*/
@Data
public class ListFill {
/**
* Название 1
*/
private String title;
/**
* Сообщество
*/
private String room;
/**
* Название 2
*/
private String title1;
/**
* Время работы
*/
private Date openTime;
/**
* Название 3
*/
private String title2;
/**
* Имя пользователя
*/
private String user;
/**
* Примечание
*/
private String remarks;
}
Соответствует Диаграмме шаблонанаИнформация о разрешении Примечания и требования соответствия переменная
/**
* экспорт информации о пользователях crm
*
* @param response ответ
* @param ids id
* @throws IOException исключение ввода-вывода
* @throws ExecutionException Исключение выполнения
* @throws InterruptedException Исключение прерывания
*/
void crmUserInfoExport(HttpServletResponse response , List<Long> ids) throws IOException, ExecutionException, InterruptedException;
@Override
public void crmUserInfoExport(HttpServletResponse response, List<Long> ids) throws IOException, ExecutionException, InterruptedException {
if (ids != null && ids.size() > 0) {
//Фиксированный каталог
String parentPath = "/Users/xguo/Desktop/" + "crmFile/";
// String path = PropertiesConfig.UPLOAD_PATH + "/crmFile/";
String childPath = String.valueOf(System.currentTimeMillis());
//путь к хранилищу
String path = parentPath + childPath;
//Создаем, если он не существует
File pathFile = new File(path);
if (!pathFile.exists()) {
pathFile.mkdirs();
}
try {
for (Long id : ids) {
//Получать Информация о контракте
UserCustomAuthorize validContractInfo = userCustomAuthorizeMapper.getUserValidContractInfo(id);
//Получать Информация о разрешении
List<RoomAuthorize> authorizeList = roomAuthorizeMapper.getByUserId(id);
//Получать合同Примечание
List<String> remarksList = userCustomAuthorizeMapper.getRemarksByUserId(id);
try {
//Экспорт заполненного шаблона Excel
EasyExcelUtil.exportCrmUserInfoList(path, validContractInfo.getName(), date1(authorizeList), date2(remarksList), getMap(validContractInfo));
} catch (Exception e) {
log.error(e.getMessage());
}
}
//Получать文件目录下的список путей к файлам
List<String> listFileNames = FileUtil.listFileNames(path);
List<String> fileNames = new ArrayList<>();
for (String fileName : listFileNames) {
fileNames.add(path + "/" + fileName);
}
//Сжатый список файлов
EasyExcelUtil.compressFileList(path + ".zip", fileNames);
//Выходной файл передается во внешний интерфейс для загрузки.
EasyExcelUtil.exportFileStream(path + ".zip", response);
}catch (Exception e){
log.error("Не удалось загрузить информацию о клиенте CRM, причина сбоя: {}",e.getMessage());
}finally {
//удаляем файл
FileUtil.del(path + ".zip");
FileUtil.del(path);
}
}
}
/**
* мономерпеременнаякарта данных
*
* @param validContractInfo эффективный Информация о контракте
* @return {@link Map}<{@link Object}, {@link Object}>
*/
private Map<Object, Object> getMap(UserCustomAuthorize validContractInfo) {
Map<Object, Object> map = MapUtils.newHashMap();
//Основная информация о клиенте
map.put("account", validContractInfo.getFuturesAccount());
map.put("phone", validContractInfo.getPhone());
map.put("address", validContractInfo.getAddress());
map.put("idCard", validContractInfo.getIdCard());
map.put("idCardValidTime", validContractInfo.getEndTime());
//Информация о контракте
map.put("id", validContractInfo.getId());
map.put("state", validContractInfo.getAuthState());
map.put("contractValidTime", validContractInfo.getEndTime());
return map;
}
/**
* Информация о список разрешении данных
*
* @param authorizeList Список полномочий
* @return {@link List}<{@link ListFill}>
*/
private List<ListFill> date1(List<RoomAuthorize> authorizeList) {
List<ListFill> data1 = new ArrayList<>();
for (int i = 0; i < authorizeList.size(); i++) {
ListFill fill = new ListFill();
fill.setTitle("Открыть Сообщество"+(i+1));
fill.setRoom(authorizeList.get(i).getRoomName());
fill.setTitle1("Дата открытия");
fill.setOpenTime(authorizeList.get(i).getAddTime());
fill.setTitle2("Открывалка");
fill.setUser(authorizeList.get(i).getAddPerson());
data1.add(fill);
}
return data1;
}
// /**
// * Информация о список разрешении данных
// *
// * @param authorizeList Список полномочий
// * @return {@link List}<{@link ListFill}>
// */
// private List<ListFill> date1(List<RoomAuthorize> authorizeList) {
// List<ListFill> data1 = new ArrayList<>();
// if (authorizeList != null && authorizeList.size() > 0) {
// for (int i = 0; i < authorizeList.size(); i++) {
// ListFill fill = new ListFill();
// fill.setTitle("Открыть Сообщество" + (i + 1));
// fill.setRoom(Optional.of(authorizeList.get(i).getRoomName()).orElse(""));
// fill.setTitle1("Дата открытия");
// fill.setOpenTime(Optional.of(authorizeList.get(i).getAddTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().toString()).orElse(""));
// fill.setTitle2("Открывалка");
// fill.setUser(Optional.of(authorizeList.get(i).getAddPerson()).orElse(""));
// data1.add(fill);
// }
// }
// return data1;
// }
/**
* Примечание список данных
*
* @param remarksList Примечаниесписок
* @return {@link List}<{@link ListFill}>
*/
private List<ListFill> date2(List<String> remarksList) {
List<ListFill> data2 = new ArrayList<>();
remarksList.forEach(remarks -> {
ListFill fill = new ListFill();
fill.setRemarks(remarks);
data2.add(fill);
});
return data2;
}
/**
* Экспортируйте информацию о клиентах CRM
*/
@GetMapping("/exportCrm")
public void exportCrm(HttpServletResponse response,@RequestParam("ids") List<Long> ids) throws IOException, ExecutionException, InterruptedException {
long startTime=System.currentTimeMillis();
iUsersService.crmUserInfoExport(response, ids);
long endTime=System.currentTimeMillis();
System.out.println("Время работы программы: "+(endTime-startTime)+"ms");
}
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import io.swagger.annotations.ApiModel;
import lombok.*;
import java.util.Date;
/**
* Объект представления экспорта статистики авторизации запроса
*
* @author xGuo
* @date 2022/06/30
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("Объект представления экспорта статистики авторизации запроса")
public class AuthorizeContractExportVo {
private static final long serialVersionUID = 1L;
@ExcelProperty(value = «Идентификатор договора», заказ = 1)
@ColumnWidth(15)
private Long id;
@ExcelProperty(value = "имя пользователя", заказ = 2)
@ColumnWidth(15)
private String name;
@ExcelProperty(value = «Счет Фонда», заказ = 3)
@ColumnWidth(15)
private String futuresAccount;
@ExcelProperty(value = «Дата подписания», приказ = 4)
@ColumnWidth(25)
private Date addTime;
@ExcelProperty(value = «Срок годности», заказ = 5)
@ColumnWidth(25)
private Date endTime;
}
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import io.swagger.annotations.ApiModel;
import lombok.*;
import java.util.Date;
/**
* Объект представления экспорта статистики авторизации запроса
*
* @author xGuo
* @date 2022/06/30
*/
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("Объект представления экспорта статистики авторизации запроса")
public class AuthorizeCancelExportVo extends AuthorizeContractExportVo {
@ExcelProperty(value = "Отписаться/время прекращения подписки",заказать = 6)
@ColumnWidth(25)
private Date updateTime;
@ExcelProperty(value = «Причина отписки/прекращения», заказ = 7)
@ColumnWidth(25)
private String remarks;
}
@Override
public void ExportAuthorizeCount (ответ HttpServletResponse) {
//Устанавливаем входной поток,Настроить домен ответа
response.setCharacterEncoding(CharEncoding.UTF_8);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
//карта статуса
Map<String, String> stateMap = new LinkedHashMap<>();
stateMap.put("all", «Всего авторизованных пользователей»);
stateMap.put("valid", «действительный пользователь»);
stateMap.put("noRoom", «Нет Сообществопользователя»);
stateMap.put("soon", «Пользователи, срок действия которых истекает»);
stateMap.put("expire7", «Пользователь с истекшим сроком действия (7 дней)»);
stateMap.put("expire30", «Пользователь с истекшим сроком действия (30 дней)»);
stateMap.put("stop", «завершить пользователя»);
stateMap.put("cancel", «Отписаться от пользователя»);
// Разные объекты записываются на разные листы
try (ExcelWriter excelWriter = EasyExcel.write(new BufferedOutputStream(response.getOutputStream()), AuthorizeContractExportVo.class).build()) {
int index = 0;
for (String key : stateMap.keySet()) {
//Получаем соответствующий список данных по статусу
List<UserCustomAuthorize> authorizes = getBaseMapper().getByAuthState(key);
//Отдельная обработка прекращения и отписки
if ("stop".equals(key) || "cancel".equals(key)) {
//Обратите внимание на метод .head(). Это ключ к вставке различных классов сущностей. Без использования этого метода невозможно получить расширенные поля.
WriteSheet build = EasyExcel.writerSheet(index, stateMap.get(key)).head(AuthorizeCancelExportVo.class).build();
List<AuthorizeCancelExportVo> cancelExportVos = BeanUtil.copyToList(authorizes, AuthorizeCancelExportVo.class, new CopyOptions());
excelWriter.write(cancelExportVos, build);
}
WriteSheet writeSheet = EasyExcel.writerSheet(index, stateMap.get(key)).build();
List<AuthorizeContractExportVo> exportVos = BeanUtil.copyToList(authorizes, AuthorizeContractExportVo.class, new CopyOptions());
excelWriter.write(exportVos, writeSheet);
index++;
}
} catch (IOException e) {
log.error("export error:{}",e.getMessage());
}
}
Пока предстоит определиться…