package com.ecep.contract.controller.vendor.approved_list;

import static com.ecep.contract.util.ExcelUtils.getRow;
import static com.ecep.contract.util.ExcelUtils.setCellValue;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddress;
import com.ecep.contract.util.ProxyUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.util.StringUtils;

import com.ecep.contract.MessageHolder;
import com.ecep.contract.MyDateTimeUtils;
import com.ecep.contract.VendorType;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyContact;
import com.ecep.contract.model.CompanyVendor;
import com.ecep.contract.model.CompanyVendorApprovedFile;
import com.ecep.contract.model.CompanyVendorApprovedItem;
import com.ecep.contract.model.CompanyVendorApprovedList;
import com.ecep.contract.model.Contract;
import com.ecep.contract.service.CompanyContactService;
import com.ecep.contract.service.CompanyOldNameService;
import com.ecep.contract.service.CompanyVendorApprovedFileService;
import com.ecep.contract.service.CompanyVendorApprovedItemService;
import com.ecep.contract.service.CompanyVendorApprovedListService;
import com.ecep.contract.service.CompanyVendorFileService;
import com.ecep.contract.service.CompanyVendorService;
import com.ecep.contract.service.ContractService;
import com.ecep.contract.task.Tasker;
import com.ecep.contract.util.ExcelUtils;
import com.ecep.contract.util.ParamUtils;

import lombok.Setter;

/**
 * 导出供方名录
 */
public class CompanyVendorApprovedListVendorExportTask extends Tasker<Object> {
    private static final Logger logger = LoggerFactory.getLogger(CompanyVendorApprovedListVendorExportTask.class);
    public static final String STR_CHANGE_VENDOR_TYPE_SHEET = "变更供应商类型";

    @Setter
    private CompanyVendorApprovedList approvedList;

    private CompanyVendorApprovedListService service;
    private CompanyVendorApprovedFileService fileService;
    private CompanyVendorApprovedItemService itemService;
    private CompanyVendorFileService companyVendorFileService;
    private CompanyOldNameService companyOldNameService;
    private ContractService contractService;
    private CompanyVendorService companyVendorService;
    private CompanyContactService companyContactService;

    private static final String FILE_NAME = "供方名录-%s.xlsx";

    private CompanyVendorApprovedListService getService() {
        if (service == null) {
            service = getBean(CompanyVendorApprovedListService.class);
        }
        return service;
    }

    private CompanyVendorApprovedFileService getFileService() {
        if (fileService == null) {
            fileService = getBean(CompanyVendorApprovedFileService.class);
        }
        return fileService;
    }

    private CompanyVendorApprovedItemService getItemService() {
        if (itemService == null) {
            itemService = getBean(CompanyVendorApprovedItemService.class);
        }
        return itemService;
    }

    private ContractService getContractService() {
        if (contractService == null) {
            contractService = getBean(ContractService.class);
        }
        return contractService;
    }

    private CompanyContactService getCompanyContactService() {
        if (companyContactService == null) {
            companyContactService = getBean(CompanyContactService.class);
        }
        return companyContactService;
    }

    private CompanyVendorService getCompanyVendorService() {
        if (companyVendorService == null) {
            companyVendorService = getBean(CompanyVendorService.class);
        }
        return companyVendorService;
    }

    private File getVendorApprovedListTemplate() {
        return getCompanyVendorService().getVendorApprovedListTemplate();
    }

    @Override
    protected Object execute(MessageHolder holder) {
        updateTitle("根据模板输出供方名录");

        try {
            exportVendorApprovedList(holder);
        } catch (Exception ex) {
            holder.error(ex.getMessage());
        }
        return null;
    }

    private void exportVendorApprovedList(MessageHolder holder) {
        LocalDate publishDate = approvedList.getPublishDate();
        if (publishDate == null) {
            holder.error("供方名录的发布日期未定义");
            return;
        }

        String path = approvedList.getPath();
        if (path == null || path.isEmpty()) {
            holder.error("供方名录的目录未定义");
            return;
        }

        File template = getVendorApprovedListTemplate();
        if (template == null) {
            holder.error("供方名录模板文件未设置，请先设置供方名录模板文件");
            return;
        }
        if (!template.exists()) {
            holder.warn("供方名录模板文件 " + template.getAbsolutePath() + " 不存在，请检查");
            return;
        }

        File dir = new File(path);
        String template_file_name = template.getName();
        String fileName = String.format(FILE_NAME, MyDateTimeUtils.format(publishDate));
        File destFile = new File(dir, fileName);

        if (destFile.exists()) {
            holder.warn("供方名录文件已经存在，" + destFile.getName());
            try (
                    InputStream inp = new FileInputStream(destFile);
                    Workbook wb = WorkbookFactory.create(inp)) {
                updateVendorApprovedList(wb, destFile, holder);
                holder.info("评估表已更新");
            } catch (Exception e) {
                holder.error(e.getMessage());
                logger.error(e.getMessage(), e);
                return;
            }
        } else {
            holder.debug("根据模板 " + template_file_name + " 创建供方名录 " + destFile.getName());
            try (
                    InputStream inp = new FileInputStream(template);
                    Workbook wb = WorkbookFactory.create(inp)) {
                updateVendorApprovedList(wb, destFile, holder);
                holder.info("供方名录已创建");
            } catch (Exception e) {
                holder.error(e.getMessage());
                logger.error(e.getMessage(), e);
                return;
            }
        }

        CompanyVendorApprovedFile approvedFile = getFileService()
                .findByName(approvedList, destFile.getName());
        if (approvedFile == null) {
            approvedFile = new CompanyVendorApprovedFile();
        }
        approvedFile.setList(approvedList);
        approvedFile.setFileName(destFile.getName());
        approvedFile.setSignDate(publishDate);

        approvedFile.setDescription("更新于 " + LocalDate.now());
        save(approvedFile);
    }

    CellStyle venodrNameCellStyle = null;
    CellStyle headerStyle = null;
    CellStyle cellStyle = null;
    CellStyle dateCellStyle = null;
    CellStyle amountCellStyle = null;

    AtomicInteger meetRow = new AtomicInteger(0);

    LocalDate endDate = null;
    LocalDate beginDate = null;

    private void updateVendorApprovedList(Workbook wb, File destFile, MessageHolder holder) throws IOException {
        endDate = approvedList.getPublishDate();
        beginDate = LocalDate.of(endDate.getYear() - 2, 1, 1);

        Font venodrNameCellFont = wb.findFont(true, IndexedColors.BLACK.getIndex(), (short) 16, "微软雅黑", false, false,
                Font.SS_NONE, Font.U_NONE);
        if (venodrNameCellFont == null) {
            venodrNameCellFont = wb.createFont();
            venodrNameCellFont.setBold(true);
            venodrNameCellFont.setColor(IndexedColors.BLACK.getIndex());
            venodrNameCellFont.setFontHeightInPoints((short) 12);
            venodrNameCellFont.setFontName("微软雅黑");
            venodrNameCellFont.setItalic(false);
            venodrNameCellFont.setStrikeout(false);
            venodrNameCellFont.setTypeOffset(Font.SS_NONE);
            venodrNameCellFont.setUnderline(Font.U_NONE);
        }

        // 遍历已有的样式，寻找匹配的
        for (int i = 0; i < wb.getNumCellStyles(); i++) {
            CellStyle existing = wb.getCellStyleAt(i);
            // updateMessage("existing CellStyle[" + i + "]");
            // updateMessage("[" + i + "] DataFormat = " + existing.getDataFormat() +
            // ", FormatString = " + existing.getDataFormatString());
            // updateMessage("[" + i + "] Fill Pattern = " + existing.getFillPattern() +
            // ", ForegroundColor = " + existing.getFillForegroundColor() +
            // ", BackgroundColor = " + existing.getFillBackgroundColor());
            // updateMessage("[" + i + "] Alignment = " + existing.getAlignment());
            // updateMessage("[" + i + "] Border Bottom = " + existing.getBorderBottom() +
            // ", Top = " + existing.getBorderTop() +
            // ", Left = " + existing.getBorderLeft() +
            // ", Right = " + existing.getBorderRight());

            if (existing.getDataFormat() == 0) {

                if (FillPatternType.SOLID_FOREGROUND.equals(existing.getFillPattern()) &&
                        existing.getFillForegroundColor() == IndexedColors.GREY_25_PERCENT.getIndex() &&
                        existing.getAlignment() == HorizontalAlignment.CENTER &&
                        existing.getVerticalAlignment() == VerticalAlignment.CENTER) {
                    headerStyle = existing;
                    continue;
                }
                if (FillPatternType.NO_FILL.equals(existing.getFillPattern()) &&
                        existing.getFillForegroundColor() == IndexedColors.AUTOMATIC.getIndex()) {
                    if (BorderStyle.THIN.equals(existing.getBorderBottom()) &&
                            BorderStyle.THIN.equals(existing.getBorderTop()) &&
                            BorderStyle.THIN.equals(existing.getBorderLeft()) &&
                            BorderStyle.THIN.equals(existing.getBorderRight())) {
                        cellStyle = existing;
                        continue;
                    }
                }
                if (venodrNameCellFont.getIndex() == existing.getFontIndex()) {
                    venodrNameCellStyle = existing;
                    continue;
                }
            }

            if (existing.getDataFormat() > 0) {
                String formatString = existing.getDataFormatString();
                if ("yyyy-mm-dd".equals(formatString)) {
                    dateCellStyle = existing;
                } else if ("#,##0".equals(formatString)) {
                    if (BorderStyle.THIN.equals(existing.getBorderBottom()) &&
                            BorderStyle.THIN.equals(existing.getBorderTop()) &&
                            BorderStyle.THIN.equals(existing.getBorderLeft()) &&
                            BorderStyle.THIN.equals(existing.getBorderRight())) {
                        if (existing.getAlignment().equals(HorizontalAlignment.RIGHT)) {
                            amountCellStyle = existing;
                        }
                    }
                }
            }
        }
        if (venodrNameCellStyle == null) {
            venodrNameCellStyle = wb.createCellStyle();
            venodrNameCellStyle.setFont(venodrNameCellFont);
            holder.debug("新建 venodrNameCellStyle");
        }
        if (dateCellStyle == null) {
            dateCellStyle = wb.createCellStyle();
            ExcelUtils.setBorder(dateCellStyle, BorderStyle.THIN);
            dateCellStyle.setDataFormat(wb.createDataFormat().getFormat("yyyy-mm-dd"));
            holder.debug("新建 contractSetupDateStyle");
        }
        if (amountCellStyle == null) {
            amountCellStyle = wb.createCellStyle();
            amountCellStyle.setDataFormat(wb.createDataFormat().getFormat("#,##0"));
            amountCellStyle.setAlignment(HorizontalAlignment.RIGHT);
            ExcelUtils.setBorder(amountCellStyle, BorderStyle.THIN);
            holder.debug("新建 amountCellStyle");
        }
        if (headerStyle == null) {
            headerStyle = wb.createCellStyle();
            headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
            ExcelUtils.setBorder(headerStyle, BorderStyle.THIN);
            headerStyle.setAlignment(HorizontalAlignment.CENTER);
            headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            holder.debug("新建 headerStyle");
        }

        if (cellStyle == null) {
            cellStyle = wb.createCellStyle();
            cellStyle.setFillForegroundColor(IndexedColors.AUTOMATIC.getIndex());
            ExcelUtils.setBorder(cellStyle, BorderStyle.THIN);
            holder.debug("新建 cellStyle");
        }

        Sheet sheet = wb.getSheetAt(0);
        updateQualifiedSheet(sheet, holder);
        sheet = wb.getSheetAt(1);
        updateTypicallySheet(wb, sheet, holder);

        // 输出到文件
        try (OutputStream fileOut = new FileOutputStream(destFile)) {
            wb.write(fileOut);
        } catch (FileNotFoundException e) {
            holder.error("写评估表时发生文件错误，请检查供方名录是否被打开中, " + e.getMessage());
            logger.error(e.getMessage(), e);
        }
    }

    private void updateTypicallySheet(Workbook wb, Sheet sheet, MessageHolder holder) {
        updateTitle("更新一般供方 Sheet");
        List<CompanyVendorApprovedItem> items = getItemService()
                .findAll(ParamUtils.builder().equals("type", VendorType.TYPICALLY)
                        .equals("list", approvedList.getId()).build(), Pageable.unpaged(Sort.by("vendor")))
                .getContent();

        holder.debug("载入新一般供方：" + items.size() + " 条");

        int prefixRow = 2;

        CellStyle borderStyle = sheet.getWorkbook().createCellStyle();
        borderStyle.setBorderTop(BorderStyle.THIN); // 上边框
        borderStyle.setBorderBottom(BorderStyle.THIN); // 下边框
        borderStyle.setBorderLeft(BorderStyle.THIN); // 左边框
        borderStyle.setBorderRight(BorderStyle.THIN); // 右边框

        List<CompanyVendorApprovedItem> meetQualified = new ArrayList<>();

        for (int i = 0; i < items.size(); i++) {
            CompanyVendorApprovedItem item = items.get(i);
            updateProgress(i, items.size());

            CompanyVendor vendor = item.getVendor();
            if (!ProxyUtils.isInitialized(vendor)) {
                vendor = getCompanyVendorService().findById(vendor.getId());
                item.setVendor(vendor);
            }
            Company company = vendor.getCompany();
            if (!ProxyUtils.isInitialized(company)) {
                company = getCompanyService().findById(company.getId());
                vendor.setCompany(company);
            }

            setCellValue(sheet, "A" + (prefixRow + i), "" + vendor.getId()).setCellStyle(borderStyle);
            String vendorName = item.getVendorName();
            if (!StringUtils.hasText(vendorName)) {
                vendorName = company.getName();
            }
            setCellValue(sheet, "B" + (prefixRow + i), vendorName).setCellStyle(borderStyle);

            setCellValue(sheet, "C" + (prefixRow + i), vendor.getPurchase()).setCellStyle(borderStyle);

            setCellValue(sheet, "D" + (prefixRow + i), vendor.getDevelopDate()).setCellStyle(borderStyle);

            CompanyContact contact = vendor.getContact();
            if (contact == null) {
                //
                contact = getCompanyContactService().findFirstByCompany(company);
            }

            if (contact != null) {
                if (!ProxyUtils.isInitialized(contact)) {
                    contact = getCompanyContactService().findById(contact.getId());
                }
                setCellValue(sheet, "E" + (prefixRow + i), contact.getName()).setCellStyle(borderStyle);
                setCellValue(sheet, "F" + (prefixRow + i), contact.getPhone()).setCellStyle(borderStyle);
            }
            setCellValue(sheet, "G" + (prefixRow + i), "合格").setCellStyle(borderStyle);
            setCellValue(sheet, "H" + (prefixRow + i), "").setCellStyle(borderStyle);

            if (Objects.equals(item.getDescription(), CompanyVendorApprovedListVendorImportTask.STR_MEET_QUALIFIED)) {
                // xx
                meetQualified.add(item);
            }
        }

        for (int i = prefixRow + items.size(); i < sheet.getLastRowNum(); i++) {
            sheet.removeRow(sheet.getRow(i));
        }

        if (!meetQualified.isEmpty()) {
            // 移除旧数据
            Sheet changeSheet = wb.getSheet(STR_CHANGE_VENDOR_TYPE_SHEET);
            if (changeSheet != null) {
                wb.removeSheetAt(wb.getSheetIndex(changeSheet));
                holder.debug("删除 " + STR_CHANGE_VENDOR_TYPE_SHEET + " Sheet");
            }

            changeSheet = wb.createSheet(STR_CHANGE_VENDOR_TYPE_SHEET);
            changeSheet.setColumnWidth(0, 2 * 256);
            changeSheet.setColumnWidth(1, 13 * 256);
            changeSheet.setColumnWidth(2, 12 * 256);
            changeSheet.setColumnWidth(3, 12 * 256);
            changeSheet.setColumnWidth(4, 12 * 256);
            changeSheet.setColumnWidth(5, 12 * 256);
            changeSheet.setColumnWidth(6, 13 * 256);
            holder.debug("创建 " + STR_CHANGE_VENDOR_TYPE_SHEET + " Sheet");

            for (CompanyVendorApprovedItem item : meetQualified) {
                outputMeetQualified(changeSheet, item, holder);
            }
        }
    }

    private void outputMeetQualified(Sheet sheet, CompanyVendorApprovedItem item, MessageHolder holder) {
        CompanyVendor vendor = item.getVendor();
        if (!ProxyUtils.isInitialized(vendor)) {
            vendor = getCompanyVendorService().findById(vendor.getId());
            item.setVendor(vendor);
        }
        Company company = vendor.getCompany();
        if (!ProxyUtils.isInitialized(company)) {
            company = getCompanyService().findById(company.getId());
            vendor.setCompany(company);
        }
        String vendorName = item.getVendorName();
        if (!StringUtils.hasText(vendorName)) {
            vendorName = company.getName();
        }

        holder.debug(vendorName + item.getDescription());
        outputMeetQualified(sheet, vendor, vendorName, item);
        holder.info("详情输出到 " + sheet.getSheetName() + " Sheet 中，请查看");
    }

    private void outputMeetQualified(Sheet sheet, CompanyVendor vendor, String vendorName,
            CompanyVendorApprovedItem item) {
        AtomicInteger row = meetRow;
        setCellValue(sheet, row.get(), 1, "供方：" + vendorName).setCellStyle(venodrNameCellStyle);
        sheet.getRow(row.get()).setHeight((short) (30 * 20));
        row.getAndIncrement();
        setCellValue(sheet, row.get(), 1, item.getDescription());
        row.getAndIncrement();

        row.getAndAdd(2);

        List<Contract> contractList = getContractService().findAllByCompanyVendor(vendor, beginDate, endDate);

        Map<Integer, List<Contract>> collected = contractList.stream()
                .collect(Collectors.groupingBy(v -> v.getSetupDate().getYear()));

        // 输出统计
        setCellValue(sheet, row.get(), 1, "按年份统计分析");
        row.getAndIncrement();
        // 表头
        setCellValue(sheet, row.get(), 1, "年份").setCellStyle(headerStyle);
        setCellValue(sheet, row.get(), 2, "合同数").setCellStyle(headerStyle);
        setCellValue(sheet, row.get(), 3, "总金额").setCellStyle(headerStyle);
        row.getAndIncrement();
        // 按年份顺序输出
        for (int year = beginDate.getYear(); year <= endDate.getYear(); year++) {
            setCellValue(sheet, row.get(), 1, year + "年").setCellStyle(cellStyle);
            List<Contract> contracts = collected.get(year);
            if (contracts == null) {
                setCellValue(sheet, row.get(), 2, 0).setCellStyle(cellStyle);
                setCellValue(sheet, row.get(), 3, 0).setCellStyle(amountCellStyle);
            } else {
                setCellValue(sheet, row.get(), 2, contracts.size()).setCellStyle(cellStyle);
                setCellValue(sheet, row.get(), 3, contracts.stream()
                        .filter(v -> v.getAmount() != null)
                        .mapToDouble(Contract::getAmount).sum()).setCellStyle(amountCellStyle);
            }
            row.getAndIncrement();
        }
        row.getAndAdd(2);

        // 输出合同详情列表
        setCellValue(sheet, row.get(), 1, "数据范围：" + beginDate + " -> " + endDate);
        row.getAndIncrement();

        // 表头
        setCellValue(sheet, row.get(), 1, "合同号").setCellStyle(headerStyle);
        setCellValue(sheet, row.get(), 2, "合同名称").setCellStyle(headerStyle);
        setCellValue(sheet, row.get(), 3, "").setCellStyle(headerStyle);
        setCellValue(sheet, row.get(), 4, "").setCellStyle(headerStyle);
        sheet.addMergedRegion(new CellRangeAddress(row.get(), row.get(), 2, 4));
        setCellValue(sheet, row.get(), 5, "提交日期").setCellStyle(headerStyle);
        setCellValue(sheet, row.get(), 6, "合同金额").setCellStyle(headerStyle);
        row.getAndIncrement();
        contractList.stream().sorted(Comparator.comparing(Contract::getSetupDate)).forEach(contract -> {
            setCellValue(sheet, row.get(), 1, contract.getCode()).setCellStyle(cellStyle);
            setCellValue(sheet, row.get(), 2, contract.getName()).setCellStyle(cellStyle);
            setCellValue(sheet, row.get(), 3, "").setCellStyle(cellStyle);
            setCellValue(sheet, row.get(), 4, "").setCellStyle(cellStyle);
            sheet.addMergedRegion(new CellRangeAddress(row.get(), row.get(), 2, 4));
            setCellValue(sheet, row.get(), 5, contract.getSetupDate()).setCellStyle(dateCellStyle);
            setCellValue(sheet, row.get(), 6, contract.getAmount()).setCellStyle(amountCellStyle);
            row.getAndIncrement();
        });
        setCellValue(sheet, row.get(), 1, "-- 结束 --");

        // 增加分页符
        sheet.setRowBreak(row.get());
        row.getAndIncrement();
    }

    private void updateQualifiedSheet(Sheet sheet, MessageHolder holder) {
        updateTitle("更新合格供方 Sheet");

        List<CompanyVendorApprovedItem> items = getItemService().findAll(
                ParamUtils.builder().equals("type", VendorType.QUALIFIED).equals("list", approvedList.getId()).build(),
                Pageable.unpaged(Sort.by("vendor.name"))).getContent();
        holder.debug("载入合共供方：" + items.size() + " 条");

        int prefixRow = 6;
        int endRow = -1;
        int totalRows = sheet.getLastRowNum();

        CellStyle[] beginCellStyles = new CellStyle[8];
        for (int i = 0; i < beginCellStyles.length; i++) {
            Row row = getRow(sheet, prefixRow + 1, true);
            if (row != null) {
                Cell cell = row.getCell(i);
                if (cell != null) {
                    beginCellStyles[i] = cell.getCellStyle();
                }
            }
        }

        CellStyle[] endCellStyles = new CellStyle[8];
        {
            for (int i = prefixRow; i < totalRows; i++) {
                Row row = sheet.getRow(i);
                if (row != null) {
                    Cell cell = row.getCell(1);
                    if (cell != null) {
                        CellStyle style = cell.getCellStyle();
                        if (style != null) {
                            if (style.getBorderBottom() == BorderStyle.THIN) {
                                endRow = i;
                                break;
                            }
                        }
                    }
                }
            }
            holder.debug("endRow = " + endRow);
            for (int i = 0; i < endCellStyles.length; i++) {
                Row row = getRow(sheet, endRow, true);
                if (row != null) {
                    Cell cell = row.getCell(i);
                    if (cell != null) {
                        endCellStyles[i] = cell.getCellStyle();
                    }
                }
            }
        }

        if (endRow > 0) {
            int rows = (endRow + 1 - (prefixRow - 1) - items.size());
            holder.debug("要移除的行数：" + rows);
            if (rows > 0) {
                sheet.shiftRows(endRow + 1, totalRows, -rows, true, true);

                // 移除后续行
                for (int i = totalRows - rows + 1; i < totalRows; i++) {
                    holder.debug("移除行：" + i);
                    Row row = sheet.getRow(i);
                    if (row != null) {
                        sheet.removeRow(row);
                    }
                }
            }
            if (rows < 0) {
                sheet.shiftRows(endRow + 1, totalRows, -rows, true, true);
            }

        }

        for (int i = 0; i < items.size(); i++) {
            CompanyVendorApprovedItem item = items.get(i);
            updateProgress(i, items.size());

            CompanyVendor vendor = item.getVendor();
            if (!ProxyUtils.isInitialized(vendor)) {
                vendor = getCompanyVendorService().findById(vendor.getId());
            }
            Company company = vendor.getCompany();
            if (!ProxyUtils.isInitialized(company)) {
                company = getCompanyService().findById(company.getId());
            }

            setCellValue(sheet, "A" + (prefixRow), "" + vendor.getId()).setCellStyle(beginCellStyles[0]);
            String vendorName = item.getVendorName();
            if (!StringUtils.hasText(vendorName)) {
                vendorName = company.getName();
            }
            setCellValue(sheet, "B" + (prefixRow), vendorName).setCellStyle(beginCellStyles[1]);

            setCellValue(sheet, "C" + (prefixRow), vendor.getPurchase()).setCellStyle(beginCellStyles[2]);

            setCellValue(sheet, "D" + (prefixRow), vendor.getDevelopDate()).setCellStyle(beginCellStyles[3]);

            CompanyContact contact = vendor.getContact();
            if (contact == null) {
                //
                contact = getCompanyContactService().findFirstByCompany(company);
            }

            if (contact == null) {
                setCellValue(sheet, "E" + (prefixRow), "").setCellStyle(beginCellStyles[4]);
                setCellValue(sheet, "F" + (prefixRow), "").setCellStyle(beginCellStyles[5]);
            } else {
                if (!ProxyUtils.isInitialized(contact)) {
                    contact = getCompanyContactService().findById(contact.getId());
                }
                setCellValue(sheet, "E" + (prefixRow), contact.getName()).setCellStyle(beginCellStyles[4]);
                setCellValue(sheet, "F" + (prefixRow), contact.getPhone()).setCellStyle(beginCellStyles[5]);
            }
            setCellValue(sheet, "G" + (prefixRow), "合格").setCellStyle(beginCellStyles[6]);
            setCellValue(sheet, "H" + (prefixRow), "").setCellStyle(beginCellStyles[7]);
            prefixRow++;
        }

        {
            // 应用最后一行样式
            Row row = getRow(sheet, prefixRow - 2, true);
            if (row != null) {
                for (int i = 0; i < endCellStyles.length; i++) {
                    Cell cell = row.getCell(i);
                    if (cell == null) {
                        cell = row.createCell(i);
                    }
                    if (cell != null) {
                        cell.setCellStyle(endCellStyles[i]);
                    }
                }
            }
        }

        // setCellValue(sheet, "B" + (prefixRow + 2), "编制/日期");

    }

    private void save(CompanyVendorApprovedFile approvedFile) {
        getFileService().save(approvedFile);
    }
}
