package cn.iocoder.yudao.module.crm.service.quotation;
|
|
import cn.iocoder.yudao.module.crm.controller.admin.quotation.vo.CrmSaleQuotationRespVO;
|
import org.apache.poi.ss.usermodel.Cell;
|
import org.apache.poi.ss.usermodel.Workbook;
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
import org.springframework.core.io.ClassPathResource;
|
|
import java.io.ByteArrayOutputStream;
|
import java.io.IOException;
|
import java.math.BigDecimal;
|
import java.time.format.DateTimeFormatter;
|
|
/** 使用客户提供的 Excel 模板生成单张销售报价单。 */
|
public final class CrmSaleQuotationExcelRenderer {
|
|
private static final String TEMPLATE = "templates/quotation/sale-quotation.xlsx";
|
private static final String DEFAULT_COMPANY = "苏珩线缆南通有限公司";
|
|
private CrmSaleQuotationExcelRenderer() {
|
}
|
|
public static byte[] render(CrmSaleQuotationRespVO quotation, String companyName,
|
String address, String contactName, String contactPhone) throws IOException {
|
if (quotation == null || quotation.getItems() == null || quotation.getItems().isEmpty()) {
|
throw new IllegalArgumentException("报价单不存在或没有产品明细,无法生成报价文件");
|
}
|
String company = companyName == null || companyName.isBlank() ? DEFAULT_COMPANY : companyName;
|
try (var input = new ClassPathResource(TEMPLATE).getInputStream();
|
var workbook = new XSSFWorkbook(input);
|
var output = new ByteArrayOutputStream()) {
|
var sheet = workbook.getSheetAt(0);
|
int extraRows = quotation.getItems().size() - 1;
|
if (extraRows > 0) {
|
sheet.shiftRows(11, sheet.getLastRowNum(), extraRows, true, false);
|
}
|
var templateRow = sheet.getRow(10);
|
for (int i = 0; i < quotation.getItems().size(); i++) {
|
var row = i == 0 ? templateRow : sheet.createRow(10 + i);
|
if (i > 0) {
|
row.setHeight(templateRow.getHeight());
|
for (int col = 0; col < 8; col++) {
|
row.createCell(col).setCellStyle(templateRow.getCell(col).getCellStyle());
|
}
|
}
|
var item = quotation.getItems().get(i);
|
string(row.getCell(0), item.getItemName() == null || item.getItemName().isBlank()
|
? item.getItemCode() : item.getItemName());
|
string(row.getCell(1), item.getItemSpecification());
|
string(row.getCell(2), item.getItemUnitName());
|
number(row.getCell(3), item.getCount());
|
number(row.getCell(4), item.getQuotationPrice());
|
BigDecimal amount = item.getTotalPrice();
|
if (amount == null && item.getCount() != null && item.getQuotationPrice() != null) {
|
amount = item.getCount().multiply(item.getQuotationPrice());
|
}
|
number(row.getCell(5), amount);
|
string(row.getCell(6), null); // 调价没有对应的系统字段
|
string(row.getCell(7), item.getRemark());
|
}
|
string(sheet.getRow(0).getCell(0), company);
|
string(sheet.getRow(2).getCell(0), "编号:" + text(quotation.getNo()));
|
string(sheet.getRow(4).getCell(1), quotation.getCustomerName());
|
string(sheet.getRow(5).getCell(1), address);
|
string(sheet.getRow(6).getCell(1), contactName);
|
string(sheet.getRow(7).getCell(1), contactPhone);
|
string(sheet.getRow(13 + extraRows).getCell(6), "报价单位:" + company);
|
string(sheet.getRow(14 + extraRows).getCell(6), "联 系 人:" + text(quotation.getOwnerUserName()));
|
string(sheet.getRow(15 + extraRows).getCell(6), "报价日期:" + (quotation.getQuotationTime() == null
|
? "" : quotation.getQuotationTime().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"))));
|
workbook.setPrintArea(0, 0, 7, 0, 17 + extraRows);
|
|
int picture = workbook.addPicture(CrmSaleQuotationDocumentRenderer.renderSeal(company), Workbook.PICTURE_TYPE_PNG);
|
var anchor = workbook.getCreationHelper().createClientAnchor();
|
anchor.setCol1(3);
|
anchor.setCol2(5);
|
anchor.setRow1(13 + extraRows);
|
anchor.setRow2(17 + extraRows);
|
sheet.createDrawingPatriarch().createPicture(anchor, picture);
|
workbook.write(output);
|
return output.toByteArray();
|
}
|
}
|
|
private static void string(Cell cell, String value) {
|
cell.setCellValue(text(value));
|
}
|
|
private static void number(Cell cell, BigDecimal value) {
|
if (value == null) {
|
cell.setBlank();
|
} else {
|
cell.setCellValue(value.doubleValue());
|
}
|
}
|
|
private static String text(String value) {
|
return value == null ? "" : value;
|
}
|
}
|