package com.bocloud.ims.service.resource;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.entity.enums.CloudProvider;
import com.bocloud.common.encrypt.DESEncrptor;
import com.bocloud.common.encrypt.Encryptor;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.Pager;
import com.bocloud.common.model.RequestContext;
import com.bocloud.common.utils.ListTool;
import com.bocloud.ims.entity.resource.CloudServer;
import com.bocloud.ims.interfaces.resource.CloudServerService;
import com.bocloud.ims.interfaces.resource.FileDownloadService;
import com.bocloud.ims.repository.resource.CloudServerRepository;
import com.google.common.collect.Maps;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 文件下载通用类
 *
 * @author wangyu
 * @version 1.0
 * @since 2020年5月26日
 */
@Service("fileDownloadService")
public class FileDownloadServiceImpl implements FileDownloadService {

    private static final Logger logger = LoggerFactory.getLogger(FileDownloadServiceImpl.class);
    @Autowired
    private CloudServerService cloudServerService;
    @Autowired
    private CloudServerRepository cloudServerRepository;
    private Encryptor encryptor = new DESEncrptor();
    private static ThreadLocal<Integer> row = new ThreadLocal<>();
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    @Override
    public BocloudResult<Map<String, Object>> vmDownload(Pager pager, String condition, String action,
                                                         RequestContext context) {
        if ("createVmPdf".equals(action)) {
            return this.createVmPdf(pager, condition, action, context);
        }
        SXSSFWorkbook workbook = new SXSSFWorkbook();
        try {
            SXSSFSheet sheet = workbook.createSheet("sheet");
            sheet.setRandomAccessWindowSize(-1);
            // 样式一，标题数据蓝色填充
            CellStyle style = workbook.createCellStyle();
            style.setFillForegroundColor(IndexedColors.ROYAL_BLUE.getIndex());
            style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            style.setBorderBottom(BorderStyle.THIN); // 下边框
            style.setBorderLeft(BorderStyle.THIN);// 左边框
            style.setBorderTop(BorderStyle.THIN);// 上边框
            style.setBorderRight(BorderStyle.THIN);// 右边框
            style.setAlignment(HorizontalAlignment.CENTER);
            // 样式二，内容样式
            CellStyle cellStyle = workbook.createCellStyle();
            cellStyle.setBorderTop(BorderStyle.THIN);// 上边框
            cellStyle.setBorderBottom(BorderStyle.THIN); // 下边框
            cellStyle.setBorderLeft(BorderStyle.THIN);// 左边框
            cellStyle.setBorderRight(BorderStyle.THIN);// 右边框
            cellStyle.setAlignment(HorizontalAlignment.CENTER);// 水平对齐方式
            cellStyle.setVerticalAlignment(VerticalAlignment.TOP);// 垂直对齐方式
            // 标题写入
            createVmReport(sheet, style, action);
            // 读写数据
            Integer total = cloudServerRepository.count(pager.getParams());
            // 每个线程处理的数量
            int numbers = 50;
            if (total < numbers) {
                excelExporter(sheet, cellStyle, 1, new Pager(1, numbers, pager.getParams(), pager.getSorter()), context,
                        action);
            } else {
                int pages = total / numbers;
                int lastNumers = total % numbers;
                int rowNumber = 1;
                List<Future<Boolean>> futures = new ArrayList<>();
                for (int i = 1; i <= pages; i++) {
                    int page = i;
                    int finalRowNumber = rowNumber;
                    futures.add(taskExecutor.submit(() -> excelExporter(sheet, cellStyle, finalRowNumber,
                            new Pager(page, numbers, pager.getParams(), pager.getSorter()), context, action)));
                    rowNumber += numbers;
                }
                // 获取结果
                for (Future<Boolean> future : futures) {
                    Boolean successful = future.get(1, TimeUnit.MINUTES);
                    if (successful) {
                        // 收到写入完成提示
                        continue;
                    }
                }
                // 整页数据的异步查询写入完成，处理最后一页不足整页的数据
                if (0 != lastNumers) {
                    excelExporter(sheet, cellStyle, pages * numbers + 1,
                            new Pager(pages + 1, numbers, pager.getParams(), pager.getSorter()), context, action);
                }
            }
            String fileName = "云主机统计数据";
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            workbook.write(byteArrayOutputStream);
            byte[] ba = byteArrayOutputStream.toByteArray();
            Map<String, Object> resultMap = Maps.newHashMap();
            resultMap.put("fileName", fileName + System.currentTimeMillis() + ".xlsx");
            resultMap.put("data", Base64.getEncoder().encodeToString(ba));
            return new BocloudResult<>(true, resultMap, "下载成功");
        } catch (Exception e) {
            logger.error("Get error message：{}", e.getMessage(), e);
            return new BocloudResult<>(false, e.getMessage());
        } finally {
            if (null != workbook) {
                try {
                    workbook.close();
                } catch (IOException e) {
                    logger.error("error message：", e);
                }
            }
        }
    }

    /**
     * 创建标题
     *
     * @param sheet
     * @param style
     * @param action
     */
    public void createVmReport(SXSSFSheet sheet, CellStyle style, String action) {
        // 模板标题处理
        String[] titles = null;
        if ("createOspVmXls".equalsIgnoreCase(action) || "createManageOneVmXls".equalsIgnoreCase(action)) { // op云主机导出
            titles = new String[]{"云主机名称", "内网IP", "浮动IP", "云主机状态", "所属平台", "创建时间", "所在主机", "所属租户", "用户名", "密码"};
        } else if ("createTencentVmXls".equalsIgnoreCase(action)) { // 腾讯云主机导出
            titles = new String[]{"云主机名称", "公网IP", "内网IP", "规格", "所属平台", "可用区", "计费方式", "密码","操作系統", "所属租户", "所属项目"};
        } else if ("createAliVmXls".equalsIgnoreCase(action)) { // 阿里云云主机导出
            titles = new String[]{"云主机名称", "内网IP", "公网IP", "状态", "规格", "操作系統", "所属租户", "所属项目"};
        } else if ("createHuaweiVmXls".equalsIgnoreCase(action)) { // 华为云主机导出
            titles = new String[]{"云主机名称", "内网IP", "公网IP", "规格", "创建时间", "所属平台", "所属租户", "所属项目", "所属域", "所属区", "密码"};
        } else if ("createTianyiVmXls".equalsIgnoreCase(action)) { // 天意云云主机导出
            titles = new String[]{"云主机名称", "云主机状态", "内网IP", "公网IP", "规格", "创建时间", "所属平台", "所属租户", "所属项目", "可用域", "可用区",
                    "密码"};
        } else if ("createQcloudVmXls".equalsIgnoreCase(action)) { // 华为云主机导出
            titles = new String[]{"云主机名称", "内网IP", "规格", "系统盘(GB)", "所属平台", "所属区域", "密码"};
        } else if ("createVspVmXls".equalsIgnoreCase(action)) { // 导出vcenter云主机(excel)
            titles = new String[]{"云主机名称", "云主机IP", "云主机状态", "规格", "所属集群", "所在主机", "所属租户", "所属业务", "所属项目", "vmTools状态", "用户名", "密码", "使用人", "申请人", "维护人","备注"};
        } else if ("createSangforVmXls".equalsIgnoreCase(action)) { // 导出vcenter云主机(excel)
            titles = new String[]{"云主机名称", "云主机IP", "云主机状态", "规格", "所在主机", "所属租户", "所属项目", "vmTools状态"};
        } else if ("createAwsVmXls".equalsIgnoreCase(action)) { // aws云主机导出
            titles = new String[]{"云主机名称", "公网IP", "内网IP", "规格", "所属平台", "可用区", "所在区域"};
        } else if ("createAllVmXls".equalsIgnoreCase(action)) {
            titles = new String[]{"云主机名称", "云主机IP", "云主机状态", "规格", "平台类型", "所属平台", "所属租户", "所属项目", "使用人", "申请人", "维护人","备注"};
        } else if ("createVolcengineVmXls".equalsIgnoreCase(action)) {
            titles = new String[]{"云主机名称", "云主机IP", "云主机状态", "规格", "所属租户", "用户名", "密码"};
        }
        logger.info("title:{}",JSON.toJSONString(titles));
        int number = -1;
        SXSSFRow row = sheet.createRow(0);
        for (String title : titles) {
            number++;
            row.createCell(number).setCellValue(title);
            sheet.getRow(0).getCell(number).setCellStyle(style);
            sheet.setColumnWidth(number, 30 * 256);
            sheet.addMergedRegion(new CellRangeAddress(0, 1, number, number));
        }
    }

    /**
     * excel导出
     *
     * @param sheet
     * @param cellStyle
     * @param rowNumber
     * @param pager
     * @param context
     * @param action
     * @return
     */
    public Boolean excelExporter(SXSSFSheet sheet, CellStyle cellStyle, int rowNumber, Pager pager,
                                 RequestContext context, String action) {
        int number = rowNumber;
        try {
            BocloudResult result = cloudServerService.list(pager, context);
            if (result.isFailed()) {
                logger.error("获取云主机数据失败", result.getMessage());
                return false;
            }
            List<CloudServer> servers = JSONObject.parseObject(JSON.toJSONString(result.getData())).getJSONArray("rows")
                    .toJavaList(CloudServer.class);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            for (CloudServer server : servers) {
                if (null != server.getIsTemplate() && server.getIsTemplate()) {
                    continue;
                }
                row.set(number += 1);
                // 创建数据初始化行
                SXSSFRow sheetRow = sheet.createRow(row.get());
                if ("createOspVmXls".equalsIgnoreCase(action) || "createManageOneVmXls".equalsIgnoreCase(action)) { // op云主机导出
                    sheetRow.createCell(0).setCellValue(server.getName());
                    sheet.getRow(row.get()).getCell(0).setCellStyle(cellStyle);
                    String privateIps = server.getPrivateIps();
                    String ipString = "";
                    List<JSONObject> objects = JSONObject.parseArray(privateIps, JSONObject.class);
                    if (!ListTool.isEmpty(objects)) {
                        for (JSONObject object : objects) {
                            List<Object> addresses = object.getJSONArray("addresses");
                            for (Object address : addresses) {
                                if (StringUtils.isEmpty(
                                        JSONObject.parseObject(JSONObject.toJSONString(address)).getString("address"))) {
                                    continue;
                                }
                                ipString +=
                                        JSONObject.parseObject(JSONObject.toJSONString(address)).getString("address") + ",";
                            }
                        }
                    }
                    if (ipString.length() > 0) {
                        ipString = ipString.substring(0, ipString.length() - 1);
                    }
                    sheetRow.createCell(1).setCellValue(ipString);
                    sheet.getRow(row.get()).getCell(1).setCellStyle(cellStyle);
                    sheetRow.createCell(2).setCellValue(server.getFloatingIp());
                    sheet.getRow(row.get()).getCell(2).setCellStyle(cellStyle);
                    sheetRow.createCell(3).setCellValue(convertStatus(server.getStatus()));
                    sheet.getRow(row.get()).getCell(3).setCellStyle(cellStyle);
                    sheetRow.createCell(4).setCellValue(server.getVendorName());
                    sheet.getRow(row.get()).getCell(4).setCellStyle(cellStyle);
                    sheetRow.createCell(5).setCellValue(sdf.format(server.getGmtVmCreate()));
                    sheet.getRow(row.get()).getCell(5).setCellStyle(cellStyle);
                    sheetRow.createCell(6).setCellValue(server.getHostName());
                    sheet.getRow(row.get()).getCell(6).setCellStyle(cellStyle);
                    sheetRow.createCell(7).setCellValue(server.getTenantName());
                    sheet.getRow(row.get()).getCell(7).setCellStyle(cellStyle);
                    sheetRow.createCell(8).setCellValue(server.getAccount() != null ? server.getAccount() : "未知");
                    sheet.getRow(row.get()).getCell(8).setCellStyle(cellStyle);
                    sheetRow.createCell(9).setCellValue(server.receivePswd() != null ? server.receivePswd() : "未知");
                    sheet.getRow(row.get()).getCell(9).setCellStyle(cellStyle);
                } else if ("createTencentVmXls".equalsIgnoreCase(action)) { // 腾讯云主机导出
                    sheetRow.createCell(0).setCellValue(server.getName());
                    sheet.getRow(row.get()).getCell(0).setCellStyle(cellStyle);
                    String publicIps = server.getPublicIps();
                    String publicIpString = "";
                    List<String> publicIpList = JSONObject.parseArray(publicIps, String.class);
                    if (null != publicIpList && !ListTool.isEmpty(publicIpList)) {
                        for (String object : publicIpList) {
                            publicIpString += object + ",";
                        }
                        if (publicIpString.length() > 0) {
                            publicIpString = publicIpString.substring(0, publicIpString.length() - 1);
                        }
                    }
                    sheetRow.createCell(1).setCellValue(publicIpString);
                    sheet.getRow(row.get()).getCell(1).setCellStyle(cellStyle);
                    String privateIps = server.getPrivateIps();
                    String privateIpString = "";
                    List<String> privateIpLists = JSONObject.parseArray(privateIps, String.class);
                    if (!ListTool.isEmpty(privateIpLists)) {
                        for (String object : privateIpLists) {
                            privateIpString += object + ",";
                        }
                        if (privateIpString.length() > 0) {
                            privateIpString = privateIpString.substring(0, privateIpString.length() - 1);
                        }
                    }
                    sheetRow.createCell(2).setCellValue(privateIpString);
                    sheet.getRow(row.get()).getCell(2).setCellStyle(cellStyle);
                    BigDecimal memory = server.getMemory();
                    String flavor = (server.getCpu() == null ? "0" : server.getCpu()) + "C/"
                            + (memory == null ? "0" : memory.intValue()) + "GB";
                    sheetRow.createCell(3).setCellValue(flavor);
                    sheet.getRow(row.get()).getCell(3).setCellStyle(cellStyle);
                    sheetRow.createCell(4).setCellValue(server.getVendorName());
                    sheet.getRow(row.get()).getCell(4).setCellStyle(cellStyle);
                    sheetRow.createCell(5).setCellValue(server.getZoneName());
                    sheet.getRow(row.get()).getCell(5).setCellStyle(cellStyle);
                    String internetChargeType = server.getInstanceChargeType();
                    String chargeType = "";
                    if (null != internetChargeType && !"".equals(internetChargeType)) {
                        if ("POSTPAID_BY_HOUR".equalsIgnoreCase(internetChargeType)) {
                            chargeType = "按小时付费";
                        } else if ("PREPAID".equalsIgnoreCase(internetChargeType)) {
                            chargeType = "包年包月";
                        } else {
                            chargeType = "未知";
                        }
                    }
                    sheetRow.createCell(6).setCellValue(chargeType);
                    sheet.getRow(row.get()).getCell(6).setCellStyle(cellStyle);
                    sheetRow.createCell(7).setCellValue(server.receivePswd() != null ? server.receivePswd() : "未知");
                    sheet.getRow(row.get()).getCell(7).setCellStyle(cellStyle);

                    sheetRow.createCell(8).setCellValue(server.getOsCategory()+" "+server.getOsName());
                    sheet.getRow(row.get()).getCell(8).setCellStyle(cellStyle);
                    sheetRow.createCell(9).setCellValue(server.getTenantName());
                    sheet.getRow(row.get()).getCell(9).setCellStyle(cellStyle);
                    sheetRow.createCell(10).setCellValue(server.getProjectName());
                    sheet.getRow(row.get()).getCell(10).setCellStyle(cellStyle);
                } else if ("createAliVmXls".equalsIgnoreCase(action)) { // 阿里云云主机导出
                    // "云主机名称", "内网IP", "公网IP", "状态", "规格", "所属租户", "所属项目"
                    sheetRow.createCell(0).setCellValue(server.getName());
                    sheet.getRow(row.get()).getCell(0).setCellStyle(cellStyle);

                    String privateIps = server.getPrivateIps();
                    String privateIpString = "";
                    List<String> privateIpLists = JSONObject.parseArray(privateIps, String.class);
                    if (!ListTool.isEmpty(privateIpLists)) {
                        for (String object : privateIpLists) {
                            privateIpString += object + ",";
                        }
                        if (privateIpString.length() > 0) {
                            privateIpString = privateIpString.substring(0, privateIpString.length() - 1);
                        }
                    }
                    sheetRow.createCell(1).setCellValue(privateIpString);
                    sheet.getRow(row.get()).getCell(1).setCellStyle(cellStyle);

                    String publicIps = server.getPublicIps();
                    String publicIpString = "";
                    List<String> publicIpList = JSONObject.parseArray(publicIps, String.class);
                    if (null != publicIpList && !ListTool.isEmpty(publicIpList)) {
                        for (String object : publicIpList) {
                            publicIpString += object + ",";
                        }
                        if (publicIpString.length() > 0) {
                            publicIpString = publicIpString.substring(0, publicIpString.length() - 1);
                        }
                    }
                    sheetRow.createCell(2).setCellValue(publicIpString);
                    sheet.getRow(row.get()).getCell(2).setCellStyle(cellStyle);

                    sheetRow.createCell(3).setCellValue(server.getStatus());
                    sheet.getRow(row.get()).getCell(3).setCellStyle(cellStyle);

                    BigDecimal memory = server.getMemory();
                    String flavor = (server.getCpu() == null ? "0" : server.getCpu()) + "C/"
                            + (memory == null ? "0" : memory.doubleValue()) + "GB";
                    sheetRow.createCell(4).setCellValue(flavor);
                    sheet.getRow(row.get()).getCell(4).setCellStyle(cellStyle);

                    String osCategory = server.getOsCategory() == null ? "" : server.getOsCategory();
                    String osName = server.getOsName() == null ? "" : server.getOsName();
                    String osVersion = server.getOsVersion() == null ? "" : server.getOsVersion();
                    sheetRow.createCell(5).setCellValue(osCategory + " " + osName + " " + osVersion);
                    sheet.getRow(row.get()).getCell(5).setCellStyle(cellStyle);

                    sheetRow.createCell(6).setCellValue(server.getTenantName());
                    sheet.getRow(row.get()).getCell(6).setCellStyle(cellStyle);

                    sheetRow.createCell(7).setCellValue(server.getProjectName());
                    sheet.getRow(row.get()).getCell(7).setCellStyle(cellStyle);

                    // sheetRow.createCell(7).setCellValue(server.getPswd() != null ? server.getPswd() : "未知");
                    // sheet.getRow(row.get()).getCell(7).setCellStyle(cellStyle);
                } else if ("createHuaweiVmXls".equalsIgnoreCase(action)) {
                    // 华为云主机导出
                    sheetRow.createCell(0).setCellValue(server.getName());
                    sheet.getRow(row.get()).getCell(0).setCellStyle(cellStyle);
                    String privateIps = server.getPrivateIps();
                    String privateIpsString = "";
                    List<JSONObject> parseArray = JSON.parseArray(privateIps, JSONObject.class);
                    if (null != parseArray && parseArray.size() > 0) {
                        for (JSONObject jsonObject : parseArray) {
                            if ("fixed".equalsIgnoreCase(jsonObject.getString("type"))) {
                                String address = jsonObject.getString("address");
                                privateIpsString += address + ",";
                            }
                        }
                    }
                    if (privateIpsString.length() > 0) {
                        privateIpsString = privateIpsString.substring(0, privateIpsString.length() - 1);
                    }
                    sheetRow.createCell(1).setCellValue(privateIpsString);
                    sheet.getRow(row.get()).getCell(1).setCellStyle(cellStyle);

                    String publicIpsString = "";
                    if (null != parseArray && parseArray.size() > 0) {
                        for (JSONObject jsonObject : parseArray) {
                            if ("floating".equalsIgnoreCase(jsonObject.getString("type"))) {
                                String address = jsonObject.getString("address");
                                publicIpsString += address + ",";
                            }
                        }
                    }
                    if (publicIpsString.length() > 0) {
                        publicIpsString = publicIpsString.substring(0, publicIpsString.length() - 1);
                    }
                    sheetRow.createCell(2).setCellValue(publicIpsString);
                    sheet.getRow(row.get()).getCell(2).setCellStyle(cellStyle);

                    Integer totalDisks = server.getDisk() == null ? 0 : server.getDisk();
                    sheetRow.createCell(3).setCellValue(
                            server.getCpu() + "C/" + server.getMemory().intValue() + "GB/" + totalDisks + "GB");
                    sheet.getRow(row.get()).getCell(3).setCellStyle(cellStyle);
                    sheetRow.createCell(4).setCellValue(sdf.format(server.getGmtVmCreate()));
                    sheet.getRow(row.get()).getCell(4).setCellStyle(cellStyle);
                    sheetRow.createCell(5).setCellValue(server.getVendorName());
                    sheet.getRow(row.get()).getCell(5).setCellStyle(cellStyle);
                    sheetRow.createCell(6).setCellValue(server.getTenantName());
                    sheet.getRow(row.get()).getCell(6).setCellStyle(cellStyle);
                    sheetRow.createCell(7).setCellValue(server.getProjectName());
                    sheet.getRow(row.get()).getCell(7).setCellStyle(cellStyle);
                    sheetRow.createCell(8).setCellValue(server.getRegionName());
                    sheet.getRow(row.get()).getCell(8).setCellStyle(cellStyle);
                    sheetRow.createCell(9).setCellValue(server.getZoneName());
                    sheet.getRow(row.get()).getCell(9).setCellStyle(cellStyle);
                    sheetRow.createCell(10).setCellValue(server.receivePswd());
                    sheet.getRow(row.get()).getCell(10).setCellStyle(cellStyle);

                } else if ("createTianyiVmXls".equalsIgnoreCase(action)) { // 天意云云主机导出
                    // "规格", "创建时间", "所属平台", "可用域", "可用区", "密码"
                    sheetRow.createCell(0).setCellValue(server.getName());
                    sheet.getRow(row.get()).getCell(0).setCellStyle(cellStyle);
                    // 状态
                    sheetRow.createCell(1).setCellValue(convertStatus(server.getStatus()));
                    sheet.getRow(row.get()).getCell(1).setCellStyle(cellStyle);
                    // 私有IP
                    String privateIps = server.getPrivateIps();
                    String ips = "";
                    List<String> parseArray = JSON.parseArray(privateIps, String.class);
                    if (!ListTool.isEmpty(parseArray)) {
                        for (String ip : parseArray) {
                            ips += ip + ",";
                        }
                    }
                    if (ips.length() > 0) {
                        ips = ips.substring(0, ips.length() - 1);
                    }
                    sheetRow.createCell(2).setCellValue(ips);
                    sheet.getRow(row.get()).getCell(2).setCellStyle(cellStyle);
                    // 公网IP
                    String publicIps = server.getPublicIps();
                    String pubIps = "";
                    List<String> publicIpArray = JSON.parseArray(publicIps, String.class);
                    if (!ListTool.isEmpty(publicIpArray)) {
                        for (String ip : publicIpArray) {
                            pubIps += ip + ",";
                        }
                    }
                    if (pubIps.length() > 0) {
                        pubIps = pubIps.substring(0, pubIps.length() - 1);
                    }
                    sheetRow.createCell(3).setCellValue(pubIps);
                    sheet.getRow(row.get()).getCell(3).setCellStyle(cellStyle);
                    // 规格
                    Integer totalDisks = server.getDisk() == null ? 0 : server.getDisk();
                    sheetRow.createCell(4).setCellValue(
                            server.getCpu() + "C/" + server.getMemory().intValue() + "GB/" + totalDisks + "GB");
                    sheet.getRow(row.get()).getCell(4).setCellStyle(cellStyle);

                    sheetRow.createCell(5).setCellValue(sdf.format(server.getGmtCreate()));
                    sheet.getRow(row.get()).getCell(5).setCellStyle(cellStyle);

                    sheetRow.createCell(6).setCellValue(server.getVendorName());
                    sheet.getRow(row.get()).getCell(6).setCellStyle(cellStyle);

                    sheetRow.createCell(7).setCellValue(server.getTenantName());
                    sheet.getRow(row.get()).getCell(7).setCellStyle(cellStyle);

                    sheetRow.createCell(8).setCellValue(server.getProjectName());
                    sheet.getRow(row.get()).getCell(8).setCellStyle(cellStyle);

                    sheetRow.createCell(9).setCellValue(server.getRegionName());
                    sheet.getRow(row.get()).getCell(9).setCellStyle(cellStyle);

                    sheetRow.createCell(10).setCellValue(server.getZoneName());
                    sheet.getRow(row.get()).getCell(10).setCellStyle(cellStyle);
                    sheetRow.createCell(11).setCellValue(server.receivePswd());
                    sheet.getRow(row.get()).getCell(11).setCellStyle(cellStyle);

                } else if ("createQcloudVmXls".equalsIgnoreCase(action)) { // 华为云主机导出
                    sheetRow.createCell(0).setCellValue(server.getName());
                    sheet.getRow(row.get()).getCell(0).setCellStyle(cellStyle);
                    String privateIps = server.getPrivateIps();
                    String privateIpString = "";
                    List<JSONObject> jSONObjectLists = JSONObject.parseArray(privateIps, JSONObject.class);
                    if (!ListTool.isEmpty(jSONObjectLists)) {
                        JSONObject jsonObject = jSONObjectLists.get(0);
                        if (null != jsonObject) {
                            privateIpString = jsonObject.getString("address");
                        }
                    }
                    sheetRow.createCell(1).setCellValue(privateIpString);
                    sheet.getRow(row.get()).getCell(1).setCellStyle(cellStyle);
                    BigDecimal memory = server.getMemory();
                    String flavor = (server.getCpu() == null ? "0" : server.getCpu()) + "C/"
                            + (memory == null ? "0" : memory.intValue()) + "GB";
                    sheetRow.createCell(2).setCellValue(flavor);
                    sheet.getRow(row.get()).getCell(2).setCellStyle(cellStyle);
                    sheetRow.createCell(3)
                            .setCellValue(String.valueOf(server.getDisk() == null ? 0 : server.getDisk()));
                    sheet.getRow(row.get()).getCell(3).setCellStyle(cellStyle);
                    sheetRow.createCell(4).setCellValue(server.getVendorName());
                    sheet.getRow(row.get()).getCell(4).setCellStyle(cellStyle);
                    sheetRow.createCell(5).setCellValue(server.getZoneName());
                    sheet.getRow(row.get()).getCell(5).setCellStyle(cellStyle);
                    sheetRow.createCell(6).setCellValue(server.receivePswd());
                    sheet.getRow(row.get()).getCell(6).setCellStyle(cellStyle);
                } else if ("createVspVmXls".equalsIgnoreCase(action)) { // 导出vcenter云主机(excel)
                    sheetRow.createCell(0).setCellValue(server.getName());
                    sheet.getRow(row.get()).getCell(0).setCellStyle(cellStyle);
                    String privateIps = server.getPrivateIps();
                    String ipString = "";
                    if (!StringUtils.isEmpty(privateIps)) {
                        try {
                            List<JSONObject> objects = JSONObject.parseArray(privateIps, JSONObject.class);
                            for (JSONObject object : objects) {
                                String address = object.getString("address");
                                if (StringUtils.isEmpty(address)) {
                                    continue;
                                }
                                ipString += address + ",";
                            }
                        }catch (Exception e){
                            //处理深信服IP
                            JSONObject object= JSONObject.parseObject(privateIps);
                            for (String cardName : object.keySet()) {
                                JSONObject address = object.getJSONObject(cardName);
                                if (address != null){
                                    for (String ip : address.keySet()) {
                                        if (StringUtils.isEmpty(ip)) {
                                            continue;
                                        }
                                        ipString += ip + ",";
                                    }
                                }
                            }

                        }

                    }
                    if (ipString.length() > 0) {
                        ipString = ipString.substring(0, ipString.length() - 1);
                    }
                    sheetRow.createCell(1).setCellValue(ipString);
                    sheet.getRow(row.get()).getCell(1).setCellStyle(cellStyle);
                    sheetRow.createCell(2).setCellValue(convertStatus(server.getStatus()));
                    sheet.getRow(row.get()).getCell(2).setCellStyle(cellStyle);
                    sheetRow.createCell(3).setCellValue(
                            server.getCpu() + "C/" + server.getMemory().intValue() + "GB/" + server.getDisk() + "GB");
                    sheet.getRow(row.get()).getCell(3).setCellStyle(cellStyle);
                    sheetRow.createCell(4).setCellValue(server.getClusterName());
                    sheet.getRow(row.get()).getCell(4).setCellStyle(cellStyle);
                    sheetRow.createCell(5).setCellValue(server.getHostName());
                    sheet.getRow(row.get()).getCell(5).setCellStyle(cellStyle);
                    
                    sheetRow.createCell(6).setCellValue(server.getTenantName());
                    sheet.getRow(row.get()).getCell(6).setCellStyle(cellStyle);

                    sheetRow.createCell(7).setCellValue(server.getBusinessName());
                    sheet.getRow(row.get()).getCell(7).setCellStyle(cellStyle);
                    
                    sheetRow.createCell(8).setCellValue(server.getProjectName());
                    sheet.getRow(row.get()).getCell(8).setCellStyle(cellStyle);
                    
                    String toolStatus = "未安装";
                    if (null != server.getToolsInstalled() && server.getToolsInstalled()) {
                        if (null != server.getToolsRunning() && server.getToolsRunning()) {
                            toolStatus = "运行中";
                        } else {
                            toolStatus = "未运行";
                        }
                    }
                    sheetRow.createCell(9).setCellValue(toolStatus);
                    sheet.getRow(row.get()).getCell(9).setCellStyle(cellStyle);
                    
                    sheetRow.createCell(10)
                            .setCellValue(String.valueOf(server.getAccount() != null ? server.getAccount() : "未知"));
                    sheet.getRow(row.get()).getCell(10).setCellStyle(cellStyle);
                    String pswd = server.getPassword();
                    if (StringUtils.isEmpty(pswd)) {
                        pswd = "未知";
                    } else {
                        pswd = encryptor.decrypt(pswd, "BocloudCMP");
                    }
                    sheetRow.createCell(11).setCellValue(pswd);
                    sheet.getRow(row.get()).getCell(11).setCellStyle(cellStyle);
                    sheetRow.createCell(12).setCellValue(server.getOwnerName());
                    sheet.getRow(row.get()).getCell(12).setCellStyle(cellStyle);
                    sheetRow.createCell(13).setCellValue(server.getCreatorName());
                    sheet.getRow(row.get()).getCell(13).setCellStyle(cellStyle);
                    sheetRow.createCell(14).setCellValue(server.getMenderName());
                    sheet.getRow(row.get()).getCell(14).setCellStyle(cellStyle);
                    sheetRow.createCell(15).setCellValue(server.getRemark());
                    sheet.getRow(row.get()).getCell(15).setCellStyle(cellStyle);
                } else if ("createSangforVmXls".equalsIgnoreCase(action)) { // 导出vcenter云主机(excel)
                    sheetRow.createCell(0).setCellValue(server.getName());
                    sheet.getRow(row.get()).getCell(0).setCellStyle(cellStyle);
                    String managerIp = server.getPrivateIps();

                    List<String> ips = new ArrayList<>();
                    if (!StringUtils.isEmpty(managerIp)) {
                        JSONObject objects = JSONObject.parseObject(managerIp, JSONObject.class);
                        Collection<Object> values = objects.values();
                        for (Object value : values) {
                            JSONObject jsonObject = (JSONObject) value;
                            Set<String> set = jsonObject.keySet();
                            ips.addAll(set);
                        }
                    }
                    String ipString = ips.stream().collect(Collectors.joining(", "));

                    sheetRow.createCell(1).setCellValue(ipString);
                    sheet.getRow(row.get()).getCell(1).setCellStyle(cellStyle);
                    sheetRow.createCell(2).setCellValue(convertStatus(server.getStatus()));
                    sheet.getRow(row.get()).getCell(2).setCellStyle(cellStyle);
                    sheetRow.createCell(3).setCellValue(
                            server.getCpu() + "C/" + server.getMemory().intValue() + "GB/" + server.getDisk() + "GB");
                    sheet.getRow(row.get()).getCell(3).setCellStyle(cellStyle);
//                    sheetRow.createCell(4).setCellValue(server.getClusterName());
//                    sheet.getRow(row.get()).getCell(4).setCellStyle(cellStyle);
                    sheetRow.createCell(4).setCellValue(server.getHostName());
                    sheet.getRow(row.get()).getCell(4).setCellStyle(cellStyle);

                    sheetRow.createCell(5).setCellValue(server.getTenantName());
                    sheet.getRow(row.get()).getCell(5).setCellStyle(cellStyle);

                    sheetRow.createCell(6).setCellValue(server.getProjectName());
                    sheet.getRow(row.get()).getCell(6).setCellStyle(cellStyle);
                    String toolStatus = "未安装";
                    if (null != server.getToolsInstalled() && server.getToolsInstalled()) {
                        toolStatus = "已安装";
                    }
                    sheetRow.createCell(7).setCellValue(toolStatus);
                    sheet.getRow(row.get()).getCell(7).setCellStyle(cellStyle);

//                    sheetRow.createCell(9)
//                            .setCellValue(String.valueOf(server.getAccount() != null ? server.getAccount() : "未知"));
//                    sheet.getRow(row.get()).getCell(9).setCellStyle(cellStyle);
//                    String pswd = server.getPassword();
//                    if (StringUtils.isEmpty(pswd)) {
//                        pswd = "未知";
//                    } else {
//                        pswd = encryptor.decrypt(pswd, "BocloudCMP");
//                    }
//                    sheetRow.createCell(10).setCellValue(pswd);
//                    sheet.getRow(row.get()).getCell(10).setCellStyle(cellStyle);
                }else if ("createAwsVmXls".equalsIgnoreCase(action)) { // aws云主机导出
                    sheetRow.createCell(0).setCellValue(server.getName());
                    sheet.getRow(row.get()).getCell(0).setCellStyle(cellStyle);
                    String publicIps = server.getPublicIps();
                    String publicIpString = "";
                    List<String> publicIpList = JSONObject.parseArray(publicIps, String.class);
                    if (null != publicIpList && !ListTool.isEmpty(publicIpList)) {
                        for (String object : publicIpList) {
                            publicIpString += object + ",";
                        }
                        if (publicIpString.length() > 0) {
                            publicIpString = publicIpString.substring(0, publicIpString.length() - 1);
                        }
                    }
                    sheetRow.createCell(1).setCellValue(publicIpString);
                    sheet.getRow(row.get()).getCell(1).setCellStyle(cellStyle);
                    String privateIps = server.getPrivateIps();
                    String privateIpString = "";
                    List<String> privateIpLists = JSONObject.parseArray(privateIps, String.class);
                    if (!ListTool.isEmpty(privateIpLists)) {
                        for (String object : privateIpLists) {
                            privateIpString += object + ",";
                        }
                        if (privateIpString.length() > 0) {
                            privateIpString = privateIpString.substring(0, privateIpString.length() - 1);
                        }
                    }
                    sheetRow.createCell(2).setCellValue(privateIpString);
                    sheet.getRow(row.get()).getCell(2).setCellStyle(cellStyle);
                    BigDecimal memory = server.getMemory();
                    String flavor = (server.getCpu() == null ? "0" : server.getCpu()) + "C/"
                            + (memory == null ? "0" : memory.intValue()) + "GB";
                    sheetRow.createCell(3).setCellValue(flavor);
                    sheet.getRow(row.get()).getCell(3).setCellStyle(cellStyle);
                    sheetRow.createCell(4).setCellValue(server.getVendorName());
                    sheet.getRow(row.get()).getCell(4).setCellStyle(cellStyle);
                    sheetRow.createCell(5).setCellValue(server.getZoneName());
                    sheet.getRow(row.get()).getCell(5).setCellStyle(cellStyle);
                    sheetRow.createCell(6).setCellValue(server.getRegionName());
                    sheet.getRow(row.get()).getCell(6).setCellStyle(cellStyle);
                } else if ("createVolcengineVmXls".equalsIgnoreCase(action)) { // 导出火山云云主机(excel)
                    sheetRow.createCell(0).setCellValue(server.getName());
                    sheet.getRow(row.get()).getCell(0).setCellStyle(cellStyle);
                    String privateIps = server.getPrivateIps();
                    String ipString = "";
                    if (!StringUtils.isEmpty(privateIps)) {
                        List<JSONObject> objects = JSONObject.parseArray(privateIps, JSONObject.class);
                        for (JSONObject object : objects) {
                            String address = object.getString("primaryIpAddress");
                            String eip = object.getString("eipAddress");
                            if (!StringUtils.isEmpty(address)) {
                                ipString += address + ",";
                            }
                            if (!StringUtils.isEmpty(eip)) {
                                ipString += eip + ",";
                            }
                        }
                    }
                    if (ipString.length() > 0) {
                        ipString = ipString.substring(0, ipString.length() - 1);
                    }
                    sheetRow.createCell(1).setCellValue(ipString);
                    sheet.getRow(row.get()).getCell(1).setCellStyle(cellStyle);
                    sheetRow.createCell(2).setCellValue(convertStatus(server.getStatus()));
                    sheet.getRow(row.get()).getCell(2).setCellStyle(cellStyle);
                    sheetRow.createCell(3).setCellValue(
                            server.getCpu() + "C/" + server.getMemory().intValue() + "GB/" + server.getDisk() + "GB");
                    sheet.getRow(row.get()).getCell(3).setCellStyle(cellStyle);
                    sheetRow.createCell(4).setCellValue(server.getTenantName());
                    sheet.getRow(row.get()).getCell(4).setCellStyle(cellStyle);
                    sheetRow.createCell(5)
                            .setCellValue(String.valueOf(server.getAccount() != null ? server.getAccount() : "未知"));
                    sheet.getRow(row.get()).getCell(5).setCellStyle(cellStyle);
                    String pswd = server.getPassword();
                    if (StringUtils.isEmpty(pswd)) {
                        pswd = "未知";
                    } else {
                        pswd = encryptor.decrypt(pswd, "BocloudCMP");
                    }
                    sheetRow.createCell(6).setCellValue(pswd);
                    sheet.getRow(row.get()).getCell(6).setCellStyle(cellStyle);
                } else if ("createAllVmXls".equalsIgnoreCase(action)) {
                    // 导出全部云主机 政务云（vc huawei tianyi）
                    // "云主机名称", "云主机IP", "云主机状态", "规格", "平台类型", "所属平台", "所属租户", "创建时间"
                    sheetRow.createCell(0).setCellValue(server.getName());
                    sheet.getRow(row.get()).getCell(0).setCellStyle(cellStyle);

                    String vendorType = server.getVendorType();
                    String privateIps = server.getPrivateIps();
                    String ipString = "";
                    switch (CloudProvider.valueOf(vendorType)) {
                        case TIANYI:
                            List<String> parseArray = JSON.parseArray(privateIps, String.class);
                            if (!ListTool.isEmpty(parseArray)) {
                                for (String ip : parseArray) {
                                    ipString += ip + ",";
                                }
                            }
                            if (ipString.length() > 0) {
                                ipString = ipString.substring(0, ipString.length() - 1);
                            }
                            break;
                        case VMWARE:
                        case HUAWEI:
                        case HCSO:
                            if (!StringUtils.isEmpty(privateIps)) {
                                List<JSONObject> objects = JSONObject.parseArray(privateIps, JSONObject.class);
                                for (JSONObject object : objects) {
                                    String address = object.getString("address");
                                    if (StringUtils.isEmpty(address)) {
                                        continue;
                                    }
                                    ipString += address + ",";
                                }
                            }
                            if (ipString.length() > 0) {
                                ipString = ipString.substring(0, ipString.length() - 1);
                            }
                            break;
                        case QCLOUD:
                            List<JSONObject> jSONObjectLists = JSONObject.parseArray(privateIps, JSONObject.class);
                            if (!ListTool.isEmpty(jSONObjectLists)) {
                                JSONObject jsonObject = jSONObjectLists.get(0);
                                if (null != jsonObject) {
                                    ipString = jsonObject.getString("address");
                                }
                            }
                            break;
                        case ALIYUN:
                        case TENCENT:
                            List<String> privateIpLists = JSONObject.parseArray(privateIps, String.class);
                            if (!ListTool.isEmpty(privateIpLists)) {
                                for (String object : privateIpLists) {
                                    ipString += object + ",";
                                }
                                if (ipString.length() > 0) {
                                    ipString = ipString.substring(0, ipString.length() - 1);
                                }
                            }
                            break;
                        case OPENSTACK:
                        case EASYSTACK:
                            List<JSONObject> objects = JSONObject.parseArray(privateIps, JSONObject.class);
                            if (!ListTool.isEmpty(objects)) {
                                for (JSONObject object : objects) {
                                    List<Object> addresses = object.getJSONArray("addresses");
                                    for (Object address : addresses) {
                                        if (StringUtils.isEmpty(
                                                JSONObject.parseObject(JSONObject.toJSONString(address)).getString("address"))) {
                                            continue;
                                        }
                                        ipString +=
                                                JSONObject.parseObject(JSONObject.toJSONString(address)).getString("address") + ",";
                                    }
                                }
                            }
                            if (ipString.length() > 0) {
                                ipString = ipString.substring(0, ipString.length() - 1);
                            }
                            break;
                        case VOLCENGINE:
                            if (!StringUtils.isEmpty(privateIps)) {
                                List<JSONObject> jsonObjects = JSONObject.parseArray(privateIps, JSONObject.class);
                                for (JSONObject object : jsonObjects) {
                                    String address = object.getString("primaryIpAddress");
                                    String eip = object.getString("eipAddress");
                                    if (!StringUtils.isEmpty(address)) {
                                        ipString += address + ",";
                                    }
                                    if (!StringUtils.isEmpty(eip)) {
                                        ipString += eip + ",";
                                    }
                                }
                            }
                            if (ipString.length() > 0) {
                                ipString = ipString.substring(0, ipString.length() - 1);
                            }
                            break;
                        default:
                            break;
                    }
                    sheetRow.createCell(1).setCellValue(ipString);
                    sheet.getRow(row.get()).getCell(1).setCellStyle(cellStyle);

                    sheetRow.createCell(2).setCellValue(convertStatus(server.getStatus()));
                    sheet.getRow(row.get()).getCell(2).setCellStyle(cellStyle);

                    BigDecimal memory = server.getMemory();
                    String flavor = (server.getCpu() == null ? "0" : server.getCpu()) + "C/"
                            + (memory == null ? "0" : memory.intValue()) + "GB/"
                            + (server.getDisk() == null ? "0" : server.getDisk()) + "GB";
                    sheetRow.createCell(3).setCellValue(flavor);
                    sheet.getRow(row.get()).getCell(3).setCellStyle(cellStyle);

                    sheetRow.createCell(4).setCellValue(server.getVendorType());
                    sheet.getRow(row.get()).getCell(4).setCellStyle(cellStyle);

                    sheetRow.createCell(5).setCellValue(server.getVendorName());
                    sheet.getRow(row.get()).getCell(5).setCellStyle(cellStyle);

                    sheetRow.createCell(6).setCellValue(server.getTenantName());
                    sheet.getRow(row.get()).getCell(6).setCellStyle(cellStyle);

                    sheetRow.createCell(7).setCellValue(server.getProjectName());
                    sheet.getRow(row.get()).getCell(7).setCellStyle(cellStyle);

                    sheetRow.createCell(8).setCellValue(server.getOwnerName());
                    sheet.getRow(row.get()).getCell(8).setCellStyle(cellStyle);
                    sheetRow.createCell(9).setCellValue(server.getCreatorName());
                    sheet.getRow(row.get()).getCell(9).setCellStyle(cellStyle);
                    sheetRow.createCell(10).setCellValue(server.getMenderName());
                    sheet.getRow(row.get()).getCell(10).setCellStyle(cellStyle);
                    sheetRow.createCell(11).setCellValue(server.getRemark());
                    sheet.getRow(row.get()).getCell(11).setCellStyle(cellStyle);
                }
            }
            return true;
        } catch (Exception e) {
            logger.error("云主机报表【" + row.get() + "行至" + (row.get() + 20) + "行】写入失败", e);
            return false;
        }
    }

    /**
     * 导出pdf
     *
     * @param pager
     * @param condition
     * @param action
     * @param context
     * @return
     */
    public BocloudResult<Map<String, Object>> createVmPdf(Pager pager, String condition, String action,
                                                          RequestContext context) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            Document document = new Document();
            PdfWriter writer = PdfWriter.getInstance(document, baos);
            document.open();
            // 设置字体
            BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            Font chineseFont = new Font(bfChinese, 11, Font.BOLD);
            Font chineseFont8 = new Font(bfChinese, 8, Font.BOLD);
            Font chineseFont24 = new Font(bfChinese, 24, Font.BOLD);// 标题字体
            Paragraph praTitle = new Paragraph("云主机统计数据", chineseFont24);
            praTitle.setAlignment(1);// 标题居中
            document.add(praTitle);
            Paragraph blankRow1 = new Paragraph(18f, " ", chineseFont);// 空格
            document.add(blankRow1);// 添加空行
            PdfPTable table = new PdfPTable(8);// 表格有多少列
            table.setHeaderRows(1);// 每页都输出表头
            PdfPCell cell1 = new PdfPCell(new Paragraph("云主机名称", chineseFont));
            PdfPCell cell2 = new PdfPCell(new Paragraph("云主机IP", chineseFont));
            PdfPCell cell3 = new PdfPCell(new Paragraph("云主机状态", chineseFont));
            PdfPCell cell4 = new PdfPCell(new Paragraph("规格", chineseFont));
            PdfPCell cell5 = new PdfPCell(new Paragraph("所在主机", chineseFont));
            PdfPCell cell6 = new PdfPCell(new Paragraph("所属集群", chineseFont));
            PdfPCell cell7 = new PdfPCell(new Paragraph("数据中心", chineseFont));
            PdfPCell cell8 = new PdfPCell(new Paragraph("所属平台", chineseFont));
            // 水平居中
            cell1.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell2.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell3.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell4.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell5.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell6.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell7.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell8.setHorizontalAlignment(Element.ALIGN_CENTER);
            table.addCell(cell1);
            table.addCell(cell2);
            table.addCell(cell3);
            table.addCell(cell4);
            table.addCell(cell5);
            table.addCell(cell6);
            table.addCell(cell7);
            table.addCell(cell8);
            // 读写数据
            Integer total = cloudServerRepository.count(new ArrayList<>());
            // 每个线程处理的数量
            int numbers = 20;
            if (total < numbers) {
                pdfExporter(table, 1, new Pager(1, numbers, pager.getParams(), pager.getSorter()), context,
                        chineseFont8);
            } else {
                int pages = total / numbers;
                int lastNumers = total % numbers;
                int rowNumber = 1;
                List<Future<Boolean>> futures = new ArrayList<>();
                for (int i = 1; i <= pages; i++) {
                    int page = i;
                    int finalRowNumber = rowNumber;
                    futures.add(taskExecutor.submit(() -> pdfExporter(table, finalRowNumber,
                            new Pager(page, numbers, pager.getParams(), pager.getSorter()), context, chineseFont8)));
                    rowNumber += numbers;
                }
                // 获取结果
                for (Future<Boolean> future : futures) {
                    Boolean successful = future.get(1, TimeUnit.MINUTES);
                    if (successful) {
                        // 收到写入完成提示
                        continue;
                    }
                }
                // 整页数据的异步查询写入完成，处理最后一页不足整页的数据
                if (0 != lastNumers) {
                    pdfExporter(table, pages * numbers + 1,
                            new Pager(numbers + 1, numbers, pager.getParams(), pager.getSorter()), context, chineseFont8);
                }
            }
            document.add(table);
            document.close();
            writer.close();
            // 下载表格到浏览器
            byte[] content = baos.toByteArray();
            Map<String, Object> resultMap = Maps.newHashMap();
            resultMap.put("fileName", "vm_" + System.currentTimeMillis() + ".pdf");
            resultMap.put("data", Base64.getEncoder().encodeToString(content));
            return new BocloudResult<>(true, resultMap, "下载成功");
        } catch (Exception e) {
            logger.error("生成文档失败", e);
            return new BocloudResult<>(false, "发生异常生成文档失败");
        }
    }

    /**
     * pdf导出
     *
     * @param table
     * @param rowNumber
     * @param pager
     * @param context
     * @param chineseFont8
     * @return
     */
    public boolean pdfExporter(PdfPTable table, int rowNumber, Pager pager, RequestContext context, Font chineseFont8) {
        try {
            BocloudResult result = cloudServerService.list(pager, context);
            if (result.isFailed()) {
                logger.error("获取云主机数据失败", result.getMessage());
                return false;
            }
            List<CloudServer> cloudServers = JSONObject.parseObject(JSON.toJSONString(result.getData()))
                    .getJSONArray("rows").toJavaList(CloudServer.class);
            for (CloudServer cloudServer : cloudServers) {
                PdfPCell cells1 = new PdfPCell(new Paragraph(cloudServer.getName(), chineseFont8));
                String privateIps = cloudServer.getPrivateIps();
                String ipString = "";
                if (!StringUtils.isEmpty(privateIps)) {
                    if (CloudProvider.OPENSTACK.name().equals(cloudServer.getVendorType())
                    		|| CloudProvider.EASYSTACK.name().equals(cloudServer.getVendorType())
                            || CloudProvider.FUSIONCLOUD.name().equals(cloudServer.getVendorType())
                            || CloudProvider.MANAGEONE.name().equals(cloudServer.getVendorType())) {
                        List<JSONObject> objects = JSONObject.parseArray(privateIps, JSONObject.class);
                        if (!ListTool.isEmpty(objects)) {
                            for (JSONObject object : objects) {
                                List<Object> addresses = object.getJSONArray("addresses");
                                for (Object address : addresses) {
                                    if (StringUtils.isEmpty(JSONObject.parseObject(JSONObject.toJSONString(address))
                                            .getString("address"))) {
                                        continue;
                                    }
                                    ipString +=
                                            JSONObject.parseObject(JSONObject.toJSONString(address)).getString("address")
                                                    + ",";
                                }
                            }
                        }
                    } else if (CloudProvider.MANAGEONE.name().equals(cloudServer.getVendorType())) {
                        List<JSONObject> objects = JSONObject.parseArray(cloudServer.getPrivateIps(), JSONObject.class);
                        for (JSONObject object : objects) {
                            ipString += object.getString("address");
                            if (object.containsKey("networkName")
                                    && !StringUtils.isEmpty(object.getString("networkName"))) {
                                ipString += "(" + object.getString("networkName") + ")\n";
                            }
                        }
                    } else if (CloudProvider.H3C.name().equals(cloudServer.getVendorType())) {
                        List<JSONObject> objects = JSONObject.parseArray(cloudServer.getPrivateIps(), JSONObject.class);
                        for (JSONObject object : objects) {
                            ipString += object.getString("address");
                        }
                    } else if (CloudProvider.ALIYUN.name().equals(cloudServer.getVendorType())) {
                        List<String> objects = JSONObject.parseArray(cloudServer.getPrivateIps(), String.class);
                        for (String object : objects) {
                            ipString += object;
                        }
                    } else if (CloudProvider.JDCLOUD.name().equals(cloudServer.getVendorType())) {
                        List<String> objects = JSONObject.parseArray(cloudServer.getPrivateIps(), String.class);
                        for (String object : objects) {
                            ipString += object;
                        }
                    } else if (CloudProvider.TENCENT.name().equals(cloudServer.getVendorType())) {
                        List<String> objects = JSONObject.parseArray(cloudServer.getPrivateIps(), String.class);
                        for (String object : objects) {
                            ipString += object;
                        }
                    } else if (CloudProvider.HUAWEI.name().equals(cloudServer.getVendorType()) || CloudProvider.HCSO.name().equals(cloudServer.getVendorType())) {
                        List<JSONObject> objects = JSONObject.parseArray(privateIps, JSONObject.class);
                        if (!ListTool.isEmpty(objects)) {
                            for (JSONObject object : objects) {
                                String address = object.getString("address");
                                ipString += address;
                            }
                        }
                    }
                }
                PdfPCell cells2 = new PdfPCell(new Paragraph(ipString, chineseFont8));
                PdfPCell cells3 = new PdfPCell(new Paragraph(convertStatus(cloudServer.getStatus()), chineseFont8));
                PdfPCell cells4 = new PdfPCell(new Paragraph(cloudServer.getCpu() + "C/"
                        + cloudServer.getMemory().intValue() + "GB/" + cloudServer.getDisk() + "GB", chineseFont8));
                PdfPCell cells5 = new PdfPCell(new Paragraph(cloudServer.getHostName(), chineseFont8));
                PdfPCell cells6 = new PdfPCell(new Paragraph(cloudServer.getClusterName(), chineseFont8));
                PdfPCell cells7 = new PdfPCell(new Paragraph(cloudServer.getVdcName(), chineseFont8));
                PdfPCell cells8 = new PdfPCell(new Paragraph(cloudServer.getVendorName(), chineseFont8));
                // 水平居中
                cells1.setHorizontalAlignment(Element.ALIGN_CENTER);
                cells2.setHorizontalAlignment(Element.ALIGN_CENTER);
                cells3.setHorizontalAlignment(Element.ALIGN_CENTER);
                cells4.setHorizontalAlignment(Element.ALIGN_CENTER);
                cells5.setHorizontalAlignment(Element.ALIGN_CENTER);
                cells6.setHorizontalAlignment(Element.ALIGN_CENTER);
                cells7.setHorizontalAlignment(Element.ALIGN_CENTER);
                cells8.setHorizontalAlignment(Element.ALIGN_CENTER);
                table.addCell(cells1);
                table.addCell(cells2);
                table.addCell(cells3);
                table.addCell(cells4);
                table.addCell(cells5);
                table.addCell(cells6);
                table.addCell(cells7);
                table.addCell(cells8);
            }
            return true;
        } catch (Exception e) {
            logger.error("云主机报表【" + row.get() + "行至" + (row.get() + 20) + "行】写入失败", e);
            return false;
        }
    }

    /**
     * 云主机状态转换
     *
     * @param status
     * @return
     */
    private static String convertStatus(String status) {
        String finalStatus = "";
        switch (status) {
            case "RUNNING":
                finalStatus = "运行中";
                break;
            case "STOPPED":
                finalStatus = "关机";
                break;
            case "STOPPING":
                finalStatus = "关机中";
                break;
            case "STARTING":
                finalStatus = "开机中";
                break;
            case "SUSPENDED":
                finalStatus = "挂起";
                break;
            case "SUSPENDING":
                finalStatus = "挂起中";
                break;
            case "ACTIVING":
                finalStatus = "激活中";
                break;
            case "PAUSED":
                finalStatus = "停止";
                break;
            case "PAUSING":
                finalStatus = "停止中";
                break;
            case "RECOVERING":
                finalStatus = "恢复中";
                break;
            case "BUILDING":
                finalStatus = "创建中";
                break;
            case "RESTARTING":
                finalStatus = "重启中";
                break;
            case "SOFTRESTARTING":
                finalStatus = "软重启中";
                break;
            case "EXPIRED":
                finalStatus = "已过期";
                break;
            case "SYNSEXCEPTION":
                finalStatus = "同步异常";
                break;
            case "RESIZING":
                finalStatus = "修改配置中";
                break;
            case "SHELVED":
                finalStatus = "搁置";
                break;
            case "RESTORING":
                finalStatus = "根磁盘快照还原中";
                break;
            case "INACCESSIBLE":
                finalStatus = "不可访问";
                break;
            case "EXCEPTION":
                finalStatus = "异常";
                break;
            default:
                finalStatus = "异常";
                break;
        }
        return finalStatus;
    }

    public static void main(String[] args) {
        String managerIp = "{\"net0\":{\"10.101.20.253\":1,\"10.101.20.252\":1},\"net1\":{\"10.101.20.251\":1,\"10.101.20.250\":1}}";
        List<String> ipString = new ArrayList<>();
        if (!StringUtils.isEmpty(managerIp)) {
            JSONObject objects = JSONObject.parseObject(managerIp, JSONObject.class);
            Collection<Object> values = objects.values();
            for (Object value : values) {
                JSONObject jsonObject = (JSONObject) value;
                Set<String> set = jsonObject.keySet();
                ipString.addAll(set);
            }
        }
        String collect = ipString.stream().collect(Collectors.joining(", "));
        System.out.println("asd");
    }
}
