liding
3 天以前 e5cc807a611a078b1c152731ff7a07e765bbb9a5
src/main/java/com/ruoyi/stock/word/WeighbridgeDocGenerator.java
@@ -5,6 +5,7 @@
import com.ruoyi.stock.dto.StockInRecordDto;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.xwpf.usermodel.XWPFTable.XWPFBorderType;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@@ -13,6 +14,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@@ -61,7 +63,7 @@
            document.write(out);
            out.flush();
            // 返回绝对路径(用于数据库存储)
            // 返回绝对路径
            return absolutePath;
        } catch (Exception e) {
@@ -84,9 +86,22 @@
    /**
     * 构建文档内容
     * @param document Word文档对象
     * @param dto 入库记录DTO
     */
    private void buildDocumentContent(XWPFDocument document, StockInRecordDto dto) {
        // 1. 添加标题 "磅码单" - 使用黑体
        // 设置纸张大小为A5横向
        CTSectPr sectPr = document.getDocument().getBody().isSetSectPr()
                ? document.getDocument().getBody().getSectPr()
                : document.getDocument().getBody().addNewSectPr();
        CTPageSz pageSize = sectPr.isSetPgSz() ? sectPr.getPgSz() : sectPr.addNewPgSz();
        pageSize.setW(BigInteger.valueOf(11906));  // A5横向宽度 210mm
        pageSize.setH(BigInteger.valueOf(8392));   // A5横向高度 148mm
        pageSize.setOrient(STPageOrientation.LANDSCAPE);
        // 标题 "磅码单"
        XWPFParagraph titlePara = document.createParagraph();
        titlePara.setAlignment(ParagraphAlignment.CENTER);
        titlePara.setSpacingAfter(200);
@@ -97,22 +112,71 @@
        titleRun.setFontSize(28);
        titleRun.setFontFamily("黑体");
        // 2. 空一行
        document.createParagraph();
        // 定义统一的页面宽度值(所有表格使用相同的总宽度)
        int pageWidth = 9000; // 统一的页面宽度值
        // 3. 头部信息(年月日和计量单位合并在一行)- 使用宋体
        XWPFParagraph headerPara = document.createParagraph();
        headerPara.setSpacingAfter(200);
        XWPFRun headerRun = headerPara.createRun();
        // 创建一行两列表格来放置日期和计量单位
        XWPFTable headerTable = document.createTable(1, 2);
        headerTable.setWidth("100%");
        // 格式化日期为 yyyy-MM-dd
        // 设置表格无边框
        headerTable.setInsideHBorder(XWPFBorderType.NONE, 0, 0, "000000");
        headerTable.setInsideVBorder(XWPFBorderType.NONE, 0, 0, "000000");
        headerTable.setTopBorder(XWPFBorderType.NONE, 0, 0, "000000");
        headerTable.setBottomBorder(XWPFBorderType.NONE, 0, 0, "000000");
        headerTable.setLeftBorder(XWPFBorderType.NONE, 0, 0, "000000");
        headerTable.setRightBorder(XWPFBorderType.NONE, 0, 0, "000000");
        // 设置表头表格列宽:日期列50%,计量单位列50%
        CTTbl headerTbl = headerTable.getCTTbl();
        CTTblGrid headerTblGrid = headerTbl.addNewTblGrid();
        // 使用统一的页面宽度
        int headerColWidth = pageWidth / 2; // 4500
        CTTblGridCol col1 = headerTblGrid.addNewGridCol();
        col1.setW(BigInteger.valueOf(headerColWidth));
        CTTblGridCol col2 = headerTblGrid.addNewGridCol();
        col2.setW(BigInteger.valueOf(headerColWidth));
        // 设置行高
        headerTable.getRow(0).setHeight(300);
        // 为表头表格的每个单元格设置宽度
        for (int colIndex = 0; colIndex < 2; colIndex++) {
            XWPFTableCell cell = headerTable.getRow(0).getCell(colIndex);
            CTTcPr tcPr = cell.getCTTc().addNewTcPr();
            CTTblWidth cellWidth = tcPr.addNewTcW();
            cellWidth.setType(STTblWidth.DXA);
            cellWidth.setW(BigInteger.valueOf(headerColWidth));
        }
        // 左侧单元格:日期(左对齐)
        XWPFTableCell dateCell = headerTable.getRow(0).getCell(0);
        dateCell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
        // 清除单元格中可能存在的默认段落
        for (int i = dateCell.getParagraphs().size() - 1; i > 0; i--) {
            dateCell.removeParagraph(i);
        }
        XWPFParagraph datePara = dateCell.getParagraphs().get(0);
        datePara.setAlignment(ParagraphAlignment.LEFT);
        // 清除段落中可能存在的默认Run
        for (int i = datePara.getRuns().size() - 1; i > 0; i--) {
            datePara.removeRun(i);
        }
        XWPFRun dateRun = datePara.createRun();
        // 格式化日期
        String weighDate = "";
        if (dto.getWeighingDate() != null) {
            try {
                // 假设 weighingDate 是 LocalDateTime 类型
                weighDate = dto.getWeighingDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            } catch (Exception e) {
                // 如果是字符串类型,尝试转换
                weighDate = dto.getWeighingDate().toString();
                if (weighDate.length() > 10) {
                    weighDate = weighDate.substring(0, 10);
@@ -120,17 +184,37 @@
            }
        }
        headerRun.setText("年月日:" + weighDate + "    计量单位:(吨)");
        headerRun.setFontSize(12);
        headerRun.setFontFamily("宋体");
        dateRun.setText("日 期:" + weighDate);
        dateRun.setFontSize(12);
        dateRun.setFontFamily("宋体");
        // 4. 创建主表格 - 4行6列(表头1行+数据1行+合计1行+空行1行)
        XWPFTable table = document.createTable(4, 6);
        // 计量单位(右对齐)
        XWPFTableCell unitCell = headerTable.getRow(0).getCell(1);
        unitCell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
        for (int i = unitCell.getParagraphs().size() - 1; i > 0; i--) {
            unitCell.removeParagraph(i);
        }
        XWPFParagraph unitPara = unitCell.getParagraphs().get(0);
        unitPara.setAlignment(ParagraphAlignment.RIGHT);
        for (int i = unitPara.getRuns().size() - 1; i > 0; i--) {
            unitPara.removeRun(i);
        }
        XWPFRun unitRun = unitPara.createRun();
        unitRun.setText("计量单位:" + dto.getUnit());
        unitRun.setFontSize(12);
        unitRun.setFontFamily("宋体");
        // 创建主表格 - 3行6列
        XWPFTable table = document.createTable(3, 6);
        // 设置表格宽度
        table.setWidth("100%");
        // 设置表格边框加粗(边框宽度设为2)
        // 设置表格边框加粗
        table.setInsideHBorder(XWPFBorderType.SINGLE, 2, 0, "000000");
        table.setInsideVBorder(XWPFBorderType.SINGLE, 2, 0, "000000");
        table.setTopBorder(XWPFBorderType.SINGLE, 2, 0, "000000");
@@ -142,7 +226,47 @@
        table.getRow(0).setHeight(400);
        table.getRow(1).setHeight(400);
        table.getRow(2).setHeight(400);
        table.getRow(3).setHeight(400);
        // 设置主表格列宽网格 - 使用相同的总宽度 pageWidth
        CTTbl mainTbl = table.getCTTbl();
        CTTblGrid mainTblGrid = mainTbl.addNewTblGrid();
        // 列宽比例
        int[] colWidths = {
                (int)(pageWidth * 0.20),
                (int)(pageWidth * 0.24),
                (int)(pageWidth * 0.14),
                (int)(pageWidth * 0.14),
                (int)(pageWidth * 0.14),
                (int)(pageWidth * 0.14)
        };
        // 确保总和等于pageWidth
        int sum = 0;
        for (int width : colWidths) {
            sum += width;
        }
        // 如果有误差,调整最后一列
        if (sum != pageWidth) {
            colWidths[5] += (pageWidth - sum);
        }
        for (int width : colWidths) {
            CTTblGridCol col = mainTblGrid.addNewGridCol();
            col.setW(BigInteger.valueOf(width));
        }
        // 为每一行的每个单元格设置具体的宽度
        for (int rowIndex = 0; rowIndex < 3; rowIndex++) {
            XWPFTableRow row = table.getRow(rowIndex);
            for (int colIndex = 0; colIndex < 6; colIndex++) {
                XWPFTableCell cell = row.getCell(colIndex);
                CTTcPr tcPr = cell.getCTTc().addNewTcPr();
                CTTblWidth cellWidth = tcPr.addNewTcW();
                cellWidth.setType(STTblWidth.DXA);
                cellWidth.setW(BigInteger.valueOf(colWidths[colIndex]));
            }
        }
        // 设置表头 - 使用黑体加粗
        String[] headers = {"车号", "品名", "毛重", "皮重", "净重", "备注"};
@@ -152,8 +276,18 @@
            cell.setText(headers[i]);
            cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
            // 清除可能存在的多余段落
            while (cell.getParagraphs().size() > 1) {
                cell.removeParagraph(1);
            }
            XWPFParagraph cellPara = cell.getParagraphs().get(0);
            cellPara.setAlignment(ParagraphAlignment.CENTER);
            while (cellPara.getRuns().size() > 1) {
                cellPara.removeRun(1);
            }
            XWPFRun cellRun = cellPara.getRuns().get(0);
            cellRun.setBold(true);
            cellRun.setFontSize(12);
@@ -169,9 +303,9 @@
        String[] data = {
                dto.getLicensePlateNo() != null ? dto.getLicensePlateNo() : "",
                getProductModelName(dto.getProductId()),
                grossWeight + "t",
                tareWeight + "t",
                netWeight + "t",
                grossWeight + dto.getUnit(),
                tareWeight + dto.getUnit(),
                netWeight + dto.getUnit(),
                dto.getRemark() != null ? dto.getRemark() : ""
        };
@@ -180,8 +314,17 @@
            cell.setText(data[i]);
            cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
            while (cell.getParagraphs().size() > 1) {
                cell.removeParagraph(1);
            }
            XWPFParagraph cellPara = cell.getParagraphs().get(0);
            cellPara.setAlignment(ParagraphAlignment.CENTER);
            while (cellPara.getRuns().size() > 1) {
                cellPara.removeRun(1);
            }
            XWPFRun cellRun = cellPara.getRuns().get(0);
            cellRun.setFontSize(12);
            cellRun.setFontFamily("宋体");
@@ -194,43 +337,68 @@
        XWPFTableCell totalLabelCell = totalRow.getCell(0);
        totalLabelCell.setText("合计(大写)");
        totalLabelCell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
        // 清除可能存在的多余段落
        while (totalLabelCell.getParagraphs().size() > 1) {
            totalLabelCell.removeParagraph(1);
        }
        XWPFParagraph totalLabelPara = totalLabelCell.getParagraphs().get(0);
        totalLabelPara.setAlignment(ParagraphAlignment.CENTER);
        // 清除可能存在的多余Run
        while (totalLabelPara.getRuns().size() > 1) {
            totalLabelPara.removeRun(1);
        }
        XWPFRun totalLabelRun = totalLabelPara.getRuns().get(0);
        totalLabelRun.setBold(true);
        totalLabelRun.setFontSize(12);
        totalLabelRun.setFontFamily("宋体");
        totalLabelRun.setFontFamily("黑体");
        XWPFTableCell contentCell = totalRow.getCell(1);
        // 将净重转换为大写
        String netWeightChinese = ChineseNumberUtil.numberToChinese(
                dto.getNetWeight() != null ? dto.getNetWeight() : BigDecimal.ZERO
        );
        contentCell.setText(netWeightChinese + "吨");
        contentCell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
        XWPFParagraph contentPara = contentCell.getParagraphs().get(0);
        contentPara.setAlignment(ParagraphAlignment.LEFT);
        XWPFRun contentRun = contentPara.getRuns().get(0);
        contentRun.setFontSize(12);
        contentRun.setFontFamily("宋体");
        // 合并第3-6列到第2列
        for (int i = 2; i < 6; i++) {
            XWPFTableCell cell = totalRow.getCell(i);
            // 设置这些单元格为合并状态(继承自第2列)
            cell.getCTTc().addNewTcPr().addNewHMerge().setVal(org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge.CONTINUE);
        XWPFTableCell startCell = totalRow.getCell(1);
        startCell.setText(netWeightChinese + dto.getUnit());
        startCell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
        while (startCell.getParagraphs().size() > 1) {
            startCell.removeParagraph(1);
        }
        // 6. 创建过磅员行(单独一行,左对齐)
        XWPFParagraph startPara = startCell.getParagraphs().get(0);
        startPara.setAlignment(ParagraphAlignment.CENTER);
        while (startPara.getRuns().size() > 1) {
            startPara.removeRun(1);
        }
        XWPFRun startRun = startPara.getRuns().get(0);
        startRun.setFontSize(12);
        startRun.setFontFamily("宋体");
        // 标记第2列为合并起始
        startCell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
        // 第3-6列合并
        for (int i = 2; i < 6; i++) {
            XWPFTableCell cell = totalRow.getCell(i);
            cell.setText("");
            cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
        }
        // 创建过磅员行(单独一行,左对齐)
        XWPFParagraph operatorPara = document.createParagraph();
        operatorPara.setSpacingAfter(100);
        operatorPara.setAlignment(ParagraphAlignment.LEFT);
        XWPFRun operatorRun = operatorPara.createRun();
        String operator = dto.getWeighingOperator() != null ? dto.getWeighingOperator() : "";
        operatorRun.setText("过磅员:" + operator);
        operatorRun.setFontSize(8);
        operatorRun.setFontSize(12);
        operatorRun.setFontFamily("宋体");
    }
    /**
@@ -242,10 +410,10 @@
        String month = String.format("%02d", now.getMonthValue());
        String day = String.format("%02d", now.getDayOfMonth());
        // 文件名格式:磅单_车牌号_年月日时分秒.docx
        // 文件名格式:磅单_车牌号_年月日.docx
        String fileName = String.format("磅单_%s_%s.docx",
                dto.getLicensePlateNo() != null ? dto.getLicensePlateNo() : "未知车牌",
                now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
                now.format(DateTimeFormatter.ofPattern("yyyyMMdd")));
        return uploadDir + File.separator + year + File.separator + month + File.separator + day + File.separator + fileName;
    }