Showing
7 changed files
with
207 additions
and
4 deletions
| @@ -40,6 +40,13 @@ | @@ -40,6 +40,13 @@ | ||
| 40 | <version>2.11.0</version> | 40 | <version>2.11.0</version> |
| 41 | </dependency> | 41 | </dependency> |
| 42 | 42 | ||
| 43 | + <!-- JLaTeXMath 用于将LaTeX渲染为图片 --> | ||
| 44 | + <dependency> | ||
| 45 | + <groupId>org.scilab.forge</groupId> | ||
| 46 | + <artifactId>jlatexmath</artifactId> | ||
| 47 | + <version>1.0.7</version> | ||
| 48 | + </dependency> | ||
| 49 | + | ||
| 43 | <!-- Lombok(可选) --> | 50 | <!-- Lombok(可选) --> |
| 44 | <dependency> | 51 | <dependency> |
| 45 | <groupId>org.projectlombok</groupId> | 52 | <groupId>org.projectlombok</groupId> |
| @@ -165,7 +165,7 @@ public class QueryContractDistributorStandardBo extends BaseBo<ContractDistribut | @@ -165,7 +165,7 @@ public class QueryContractDistributorStandardBo extends BaseBo<ContractDistribut | ||
| 165 | * 发货状态 | 165 | * 发货状态 |
| 166 | */ | 166 | */ |
| 167 | @ApiModelProperty(value = "发货状态") | 167 | @ApiModelProperty(value = "发货状态") |
| 168 | - private String shippingStatus; | 168 | + private String shippingStatusName; |
| 169 | 169 | ||
| 170 | public QueryContractDistributorStandardBo() { | 170 | public QueryContractDistributorStandardBo() { |
| 171 | 171 |
| @@ -38,6 +38,7 @@ import com.lframework.xingyun.sc.entity.ContractFramework; | @@ -38,6 +38,7 @@ import com.lframework.xingyun.sc.entity.ContractFramework; | ||
| 38 | import com.lframework.xingyun.sc.service.contract.ContractDistributorLineService; | 38 | import com.lframework.xingyun.sc.service.contract.ContractDistributorLineService; |
| 39 | import com.lframework.xingyun.sc.service.contract.ContractDistributorStandardService; | 39 | import com.lframework.xingyun.sc.service.contract.ContractDistributorStandardService; |
| 40 | import com.lframework.xingyun.sc.service.contract.ContractFrameworkService; | 40 | import com.lframework.xingyun.sc.service.contract.ContractFrameworkService; |
| 41 | +import com.lframework.xingyun.sc.utils.LatexFormulaExcelExporterUtil; | ||
| 41 | import com.lframework.xingyun.sc.vo.contract.createVo.CreateContractDistributorStandardVo; | 42 | import com.lframework.xingyun.sc.vo.contract.createVo.CreateContractDistributorStandardVo; |
| 42 | import com.lframework.xingyun.sc.vo.contract.queryVo.QueryContractDistributorStandardVo; | 43 | import com.lframework.xingyun.sc.vo.contract.queryVo.QueryContractDistributorStandardVo; |
| 43 | import com.lframework.xingyun.sc.vo.contract.updateVo.UpdateContractDistributorStandardVo; | 44 | import com.lframework.xingyun.sc.vo.contract.updateVo.UpdateContractDistributorStandardVo; |
| @@ -66,6 +67,7 @@ import java.net.URLEncoder; | @@ -66,6 +67,7 @@ import java.net.URLEncoder; | ||
| 66 | import java.time.LocalDate; | 67 | import java.time.LocalDate; |
| 67 | import java.time.format.DateTimeFormatter; | 68 | import java.time.format.DateTimeFormatter; |
| 68 | import java.util.*; | 69 | import java.util.*; |
| 70 | +import java.util.List; | ||
| 69 | import java.util.function.Function; | 71 | import java.util.function.Function; |
| 70 | import java.util.stream.Collectors; | 72 | import java.util.stream.Collectors; |
| 71 | 73 | ||
| @@ -139,6 +141,7 @@ public class ContractDistributorStandardController extends DefaultBaseController | @@ -139,6 +141,7 @@ public class ContractDistributorStandardController extends DefaultBaseController | ||
| 139 | } | 141 | } |
| 140 | 142 | ||
| 141 | vo.setDeptIdList(sysDeptList.stream().map(SysDept::getId).collect(Collectors.toList())); | 143 | vo.setDeptIdList(sysDeptList.stream().map(SysDept::getId).collect(Collectors.toList())); |
| 144 | + vo.setCreateById(SecurityUtil.getCurrentUser().getId()); | ||
| 142 | } | 145 | } |
| 143 | 146 | ||
| 144 | PageResult<ContractDistributorStandard> pageResult = contractDistributorStandardService.query(getPageIndex(vo), getPageSize(vo), vo); | 147 | PageResult<ContractDistributorStandard> pageResult = contractDistributorStandardService.query(getPageIndex(vo), getPageSize(vo), vo); |
| @@ -443,6 +446,7 @@ public class ContractDistributorStandardController extends DefaultBaseController | @@ -443,6 +446,7 @@ public class ContractDistributorStandardController extends DefaultBaseController | ||
| 443 | Wrapper<ContractFramework> contractFrameworkWrapper = Wrappers.lambdaQuery(ContractFramework.class) | 446 | Wrapper<ContractFramework> contractFrameworkWrapper = Wrappers.lambdaQuery(ContractFramework.class) |
| 444 | .eq(ContractFramework::getCustomerId, data.getBuyer()) | 447 | .eq(ContractFramework::getCustomerId, data.getBuyer()) |
| 445 | .ge(ContractFramework::getValidityTime, LocalDate.now()) | 448 | .ge(ContractFramework::getValidityTime, LocalDate.now()) |
| 449 | + .ge(ContractFramework::getCompany, data.getSupplier()) | ||
| 446 | .eq(ContractFramework::getHasFrameworkAgreement, true); | 450 | .eq(ContractFramework::getHasFrameworkAgreement, true); |
| 447 | List<ContractFramework> contractFrameworkList = contractFrameworkService.list(contractFrameworkWrapper); | 451 | List<ContractFramework> contractFrameworkList = contractFrameworkService.list(contractFrameworkWrapper); |
| 448 | List<String> productNameList = new ArrayList<>(); | 452 | List<String> productNameList = new ArrayList<>(); |
| @@ -483,7 +487,38 @@ public class ContractDistributorStandardController extends DefaultBaseController | @@ -483,7 +487,38 @@ public class ContractDistributorStandardController extends DefaultBaseController | ||
| 483 | 487 | ||
| 484 | setCellValue(sheet, startRow, 1, contractDistributorLineBo.getProductName()); // B列 | 488 | setCellValue(sheet, startRow, 1, contractDistributorLineBo.getProductName()); // B列 |
| 485 | setCellValue(sheet, startRow, 4, contractDistributorLineBo.getBrand()); // D列 | 489 | setCellValue(sheet, startRow, 4, contractDistributorLineBo.getBrand()); // D列 |
| 486 | -// setCellValue(sheet, startRow, 5, contractDistributorLineBo.getSpecification()); // E列 | 490 | +// setCellValue(sheet, startRow, 5, convertToSimpleLatex(components)); // E列 |
| 491 | + | ||
| 492 | + List<LatexFormulaExcelExporterUtil.FormulaComponent> formulaComponentList = new ArrayList<>(3); | ||
| 493 | + if (contractDistributorLineBo.getThickness() != null) { | ||
| 494 | + LatexFormulaExcelExporterUtil.FormulaComponent formulaComponent = new LatexFormulaExcelExporterUtil.FormulaComponent(); | ||
| 495 | + formulaComponent.setBase(contractDistributorLineBo.getThickness()); | ||
| 496 | + formulaComponent.setSup(contractDistributorLineBo.getThicknessTolPos()); | ||
| 497 | + formulaComponent.setSub(contractDistributorLineBo.getThicknessTolNeg()); | ||
| 498 | + formulaComponentList.add(formulaComponent); | ||
| 499 | + } | ||
| 500 | + | ||
| 501 | + if (contractDistributorLineBo.getWidth() != null) { | ||
| 502 | + LatexFormulaExcelExporterUtil.FormulaComponent formulaComponent = new LatexFormulaExcelExporterUtil.FormulaComponent(); | ||
| 503 | + formulaComponent.setBase(contractDistributorLineBo.getWidth()); | ||
| 504 | + formulaComponent.setSup(contractDistributorLineBo.getWidthTolPos()); | ||
| 505 | + formulaComponent.setSub(contractDistributorLineBo.getWidthTolNeg()); | ||
| 506 | + formulaComponentList.add(formulaComponent); | ||
| 507 | + } | ||
| 508 | + | ||
| 509 | + if (contractDistributorLineBo.getLength() != null) { | ||
| 510 | + LatexFormulaExcelExporterUtil.FormulaComponent formulaComponent = new LatexFormulaExcelExporterUtil.FormulaComponent(); | ||
| 511 | + formulaComponent.setBase(contractDistributorLineBo.getLength()); | ||
| 512 | + formulaComponent.setSup(contractDistributorLineBo.getLengthTolPos()); | ||
| 513 | + formulaComponent.setSub(contractDistributorLineBo.getLengthTolNeg()); | ||
| 514 | + formulaComponentList.add(formulaComponent); | ||
| 515 | + } | ||
| 516 | + | ||
| 517 | + String latex = LatexFormulaExcelExporterUtil.convertToLatex(formulaComponentList); | ||
| 518 | + if (StringUtils.isNotBlank(latex)) { | ||
| 519 | + LatexFormulaExcelExporterUtil.insertLatexImageToCell(workbook, sheet, latex, startRow, 5);// E列 | ||
| 520 | + } | ||
| 521 | + | ||
| 487 | setCellValue(sheet, startRow, 6, contractDistributorLineBo.getStatus()); // F列 | 522 | setCellValue(sheet, startRow, 6, contractDistributorLineBo.getStatus()); // F列 |
| 488 | setCellValue(sheet, startRow, 7, contractDistributorLineBo.getQuantity()); // G列 | 523 | setCellValue(sheet, startRow, 7, contractDistributorLineBo.getQuantity()); // G列 |
| 489 | setCellValue(sheet, startRow, 9, contractDistributorLineBo.getUnitPrice()); // I列 | 524 | setCellValue(sheet, startRow, 9, contractDistributorLineBo.getUnitPrice()); // I列 |
xingyun-sc/src/main/java/com/lframework/xingyun/sc/utils/LatexFormulaExcelExporterUtil.java
0 → 100644
| 1 | +package com.lframework.xingyun.sc.utils; | ||
| 2 | + | ||
| 3 | +import lombok.Data; | ||
| 4 | +import lombok.extern.slf4j.Slf4j; | ||
| 5 | +import org.apache.commons.collections4.CollectionUtils; | ||
| 6 | +import org.apache.poi.ss.usermodel.*; | ||
| 7 | +import org.scilab.forge.jlatexmath.TeXConstants; | ||
| 8 | +import org.scilab.forge.jlatexmath.TeXFormula; | ||
| 9 | +import org.scilab.forge.jlatexmath.TeXIcon; | ||
| 10 | + | ||
| 11 | +import javax.imageio.ImageIO; | ||
| 12 | +import javax.swing.*; | ||
| 13 | +import java.awt.*; | ||
| 14 | +import java.awt.Color; | ||
| 15 | +import java.awt.image.BufferedImage; | ||
| 16 | +import java.io.ByteArrayOutputStream; | ||
| 17 | +import java.io.IOException; | ||
| 18 | +import java.math.BigDecimal; | ||
| 19 | +import java.util.List; | ||
| 20 | + | ||
| 21 | +@Slf4j | ||
| 22 | +public class LatexFormulaExcelExporterUtil { | ||
| 23 | + | ||
| 24 | + public static String convertToLatex(List<FormulaComponent> componentList) { | ||
| 25 | + if (CollectionUtils.isEmpty(componentList)) { | ||
| 26 | + return ""; | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + | ||
| 30 | + StringBuilder latex = new StringBuilder(); | ||
| 31 | + latex.append("\\mathbf{"); | ||
| 32 | + for (int i = 0; i < componentList.size(); i++) { | ||
| 33 | + FormulaComponent comp = componentList.get(i); | ||
| 34 | + if (comp.getBase() == null) { | ||
| 35 | + continue; | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + latex.append(comp.getBase().stripTrailingZeros()); | ||
| 39 | + if (comp.getSup() != null) { | ||
| 40 | + latex.append("^{+").append(comp.getSup().stripTrailingZeros()).append("}"); | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + if (comp.getSub() != null) { | ||
| 44 | + latex.append("_{-").append(comp.getSub().stripTrailingZeros()).append("}"); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + if (i < componentList.size() - 1) { | ||
| 48 | + latex.append(" \\times "); | ||
| 49 | + } | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + latex.append("}"); | ||
| 53 | + return latex.toString(); | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + /** | ||
| 57 | + * 将LaTeX公式字符串渲染为图片字节数组 | ||
| 58 | + * | ||
| 59 | + * @param latex LaTeX公式字符串,如 "\\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}" | ||
| 60 | + * @param fontSize 渲染的字体大小 | ||
| 61 | + * @return 图片的字节数组 (PNG格式) | ||
| 62 | + * @throws IOException 如果渲染或转换失败 | ||
| 63 | + */ | ||
| 64 | + public static byte[] latexToImageBytes(String latex, int fontSize) throws IOException { | ||
| 65 | + try { | ||
| 66 | + // 1. 创建TeXFormula对象,解析LaTeX字符串 | ||
| 67 | + TeXFormula formula = new TeXFormula(latex); | ||
| 68 | + | ||
| 69 | + // 2. 创建TeXIcon,指定样式和大小 | ||
| 70 | + TeXIcon icon = formula.createTeXIcon(TeXConstants.STYLE_DISPLAY, fontSize); | ||
| 71 | + | ||
| 72 | + // 3. 创建一个BufferedImage,用于绘制公式 | ||
| 73 | + BufferedImage image = new BufferedImage( | ||
| 74 | + icon.getIconWidth(), | ||
| 75 | + icon.getIconHeight(), | ||
| 76 | + BufferedImage.TYPE_INT_ARGB | ||
| 77 | + ); | ||
| 78 | + | ||
| 79 | + // 4. 获取Graphics2D进行绘制 | ||
| 80 | + Graphics2D g2 = image.createGraphics(); | ||
| 81 | + | ||
| 82 | + // 设置最高质量的渲染提示 | ||
| 83 | + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); | ||
| 84 | + g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); | ||
| 85 | + g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); | ||
| 86 | + g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); | ||
| 87 | + g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); | ||
| 88 | + g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); | ||
| 89 | + g2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); | ||
| 90 | + g2.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE); | ||
| 91 | + | ||
| 92 | + // 设置背景为白色 | ||
| 93 | + g2.setColor(Color.WHITE); | ||
| 94 | + g2.fillRect(0, 0, icon.getIconWidth(), icon.getIconHeight()); | ||
| 95 | + | ||
| 96 | + // 设置公式颜色为黑色 | ||
| 97 | + JLabel label = new JLabel(); | ||
| 98 | + label.setForeground(Color.BLACK); | ||
| 99 | + | ||
| 100 | + // 5. 将公式绘制到BufferedImage上 | ||
| 101 | + icon.paintIcon(label, g2, 0, 0); | ||
| 102 | + g2.dispose(); | ||
| 103 | + | ||
| 104 | + // 6. 将BufferedImage转换为字节数组 | ||
| 105 | + ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ||
| 106 | + ImageIO.write(image, "png", baos); | ||
| 107 | + | ||
| 108 | + return baos.toByteArray(); | ||
| 109 | + | ||
| 110 | + } catch (Exception e) { | ||
| 111 | + throw new IOException("LaTeX渲染失败: " + e.getMessage(), e); | ||
| 112 | + } | ||
| 113 | + } | ||
| 114 | + | ||
| 115 | + /** | ||
| 116 | + * 将LaTeX公式作为图片插入到指定单元格 | ||
| 117 | + */ | ||
| 118 | + public static void insertLatexImageToCell(Workbook workbook, Sheet sheet, String latex, int rowIndex, int colIndex) throws IOException { | ||
| 119 | + // 1. 将LaTeX渲染为图片字节 | ||
| 120 | + byte[] imageBytes = latexToImageBytes(latex, 48); | ||
| 121 | + | ||
| 122 | + // 2. 将图片添加到工作簿 | ||
| 123 | + int pictureIdx = workbook.addPicture(imageBytes, Workbook.PICTURE_TYPE_PNG); | ||
| 124 | + | ||
| 125 | + // 3. 创建绘图对象 | ||
| 126 | + Drawing<?> drawing = sheet.createDrawingPatriarch(); | ||
| 127 | + | ||
| 128 | + // 4. 创建锚点,确定图片位置 | ||
| 129 | + ClientAnchor anchor = workbook.getCreationHelper().createClientAnchor(); | ||
| 130 | + anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE); | ||
| 131 | + anchor.setCol1(colIndex); // C列 (从0开始计数) | ||
| 132 | + anchor.setRow1(rowIndex); // 当前数据行 (表头在第0行) | ||
| 133 | + anchor.setCol2(colIndex + 1); // 结束于D列 | ||
| 134 | + anchor.setRow2(rowIndex + 1); // 结束于下一行 | ||
| 135 | + | ||
| 136 | + // 设置较小的起始偏移 | ||
| 137 | + anchor.setDx1(50); // 水平偏移(建议值:10-100) | ||
| 138 | + anchor.setDy1(25); // 垂直偏移(建议值:10-50) | ||
| 139 | + | ||
| 140 | + | ||
| 141 | + // 5. 创建图片并插入 | ||
| 142 | + Picture pict = drawing.createPicture(anchor, pictureIdx); | ||
| 143 | + | ||
| 144 | + // 6. 自动调整图片大小以适应单元格 (可选) | ||
| 145 | + // 取消注释此行使图片自动适应锚点区域 | ||
| 146 | +// pict.resize(0.95); // 缩小到90%,自然产生边距 | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + @Data | ||
| 150 | + public static class FormulaComponent { | ||
| 151 | + BigDecimal base; | ||
| 152 | + BigDecimal sup; | ||
| 153 | + BigDecimal sub; | ||
| 154 | + } | ||
| 155 | +} |
| @@ -79,5 +79,8 @@ public class QueryContractDistributorStandardVo extends PageVo implements BaseVo | @@ -79,5 +79,8 @@ public class QueryContractDistributorStandardVo extends PageVo implements BaseVo | ||
| 79 | */ | 79 | */ |
| 80 | @ApiModelProperty(value = "标准合同是否审核完成(AUDIT:审核中,PASS:审核通过,REFUSE:已驳回,CANCEL:已取消)") | 80 | @ApiModelProperty(value = "标准合同是否审核完成(AUDIT:审核中,PASS:审核通过,REFUSE:已驳回,CANCEL:已取消)") |
| 81 | private String standardApproved; | 81 | private String standardApproved; |
| 82 | + | ||
| 83 | + @ApiModelProperty("创建人ID") | ||
| 84 | + private String createById; | ||
| 82 | } | 85 | } |
| 83 | 86 |
| @@ -143,15 +143,18 @@ | @@ -143,15 +143,18 @@ | ||
| 143 | </if> | 143 | </if> |
| 144 | <if test="vo.status != null"> | 144 | <if test="vo.status != null"> |
| 145 | AND tb.status LIKE CONCAT(#{vo.status}, '%') | 145 | AND tb.status LIKE CONCAT(#{vo.status}, '%') |
| 146 | + <if test="vo.status == 'DRAFT' and vo.createById != null"> | ||
| 147 | + AND tb.create_by_id = #{vo.createById} | ||
| 148 | + </if> | ||
| 146 | </if> | 149 | </if> |
| 147 | <if test="vo.type != null"> | 150 | <if test="vo.type != null"> |
| 148 | AND tb.type = #{vo.type} | 151 | AND tb.type = #{vo.type} |
| 149 | </if> | 152 | </if> |
| 150 | <if test="vo.formalApproved != null"> | 153 | <if test="vo.formalApproved != null"> |
| 151 | - AND tb.formalApproved = #{vo.formalApproved} | 154 | + AND tb.formal_approved = #{vo.formalApproved} |
| 152 | </if> | 155 | </if> |
| 153 | <if test="vo.standardApproved != null"> | 156 | <if test="vo.standardApproved != null"> |
| 154 | - AND tb.standardApproved = #{vo.standardApproved} | 157 | + AND tb.standard_approved = #{vo.standardApproved} |
| 155 | </if> | 158 | </if> |
| 156 | </where> | 159 | </where> |
| 157 | order by tb.create_time desc | 160 | order by tb.create_time desc |
No preview for this file type