Commit b414d4c54d956c0a7cdc33af339fd708bc94e640

Authored by 房远帅
1 parent 99c0b4c3

合同:打印模板调整

@@ -1253,13 +1253,41 @@ public class ContractDistributorStandardController extends DefaultBaseController @@ -1253,13 +1253,41 @@ public class ContractDistributorStandardController extends DefaultBaseController
1253 } 1253 }
1254 } 1254 }
1255 1255
  1256 + int contractSpecFontSize = Integer.MAX_VALUE;
  1257 + for (SpecImageCell specCell : specImageCells) {
  1258 + int currentFontSize = LatexFormulaExcelExporterUtil.calculateContractReferenceFontSize(
  1259 + workbook,
  1260 + sheet,
  1261 + specCell.rowIndex,
  1262 + specCell.colIndex
  1263 + );
  1264 + contractSpecFontSize = Math.min(contractSpecFontSize, currentFontSize);
  1265 + }
  1266 + if (contractSpecFontSize == Integer.MAX_VALUE) {
  1267 + contractSpecFontSize = 16;
  1268 + }
  1269 +
  1270 + double contractSpecScale = 1.0;
  1271 + for (SpecImageCell specCell : specImageCells) {
  1272 + double currentScale = LatexFormulaExcelExporterUtil.calculateContractReferenceFitScale(
  1273 + workbook,
  1274 + sheet,
  1275 + specCell.rowIndex,
  1276 + specCell.colIndex,
  1277 + contractSpecFontSize
  1278 + );
  1279 + contractSpecScale = Math.min(contractSpecScale, currentScale);
  1280 + }
  1281 +
1256 for (SpecImageCell specCell : specImageCells) { 1282 for (SpecImageCell specCell : specImageCells) {
1257 LatexFormulaExcelExporterUtil.insertContractLatexImageToCellFillTemplate( 1283 LatexFormulaExcelExporterUtil.insertContractLatexImageToCellFillTemplate(
1258 workbook, 1284 workbook,
1259 sheet, 1285 sheet,
1260 specCell.latex, 1286 specCell.latex,
1261 specCell.rowIndex, 1287 specCell.rowIndex,
1262 - specCell.colIndex 1288 + specCell.colIndex,
  1289 + contractSpecFontSize,
  1290 + contractSpecScale
1263 ); 1291 );
1264 } 1292 }
1265 1293
@@ -24,6 +24,9 @@ import java.util.List; @@ -24,6 +24,9 @@ import java.util.List;
24 @Slf4j 24 @Slf4j
25 public class LatexFormulaExcelExporterUtil { 25 public class LatexFormulaExcelExporterUtil {
26 26
  27 + private static final String CONTRACT_SPEC_REFERENCE_LATEX =
  28 + "\\mathbf{\\mathrm{22^{+0.2}_{+0.1}\\!\\times\\!22^{+0.2}_{+0.1}\\!\\times\\!22^{+0.2}_{+0.1}}}";
  29 +
27 public static String convertToLatex(List<FormulaComponent> componentList) { 30 public static String convertToLatex(List<FormulaComponent> componentList) {
28 if (CollectionUtils.isEmpty(componentList)) { 31 if (CollectionUtils.isEmpty(componentList)) {
29 return ""; 32 return "";
@@ -97,11 +100,12 @@ public class LatexFormulaExcelExporterUtil { @@ -97,11 +100,12 @@ public class LatexFormulaExcelExporterUtil {
97 return ""; 100 return "";
98 } 101 }
99 102
  103 + String referenceComponentLatex = resolveReferenceComponentLatex(componentList);
100 int missing = Math.max(0, 3 - nonNullCount); 104 int missing = Math.max(0, 3 - nonNullCount);
101 if (missing > 0) { 105 if (missing > 0) {
102 StringBuilder phantom = new StringBuilder(); 106 StringBuilder phantom = new StringBuilder();
103 for (int i = 0; i < missing; i++) { 107 for (int i = 0; i < missing; i++) {
104 - phantom.append(" \\times 000^{+00}_{+00}"); 108 + phantom.append(" \\times ").append(referenceComponentLatex);
105 } 109 }
106 actual = actual + "\\phantom{" + phantom + "}"; 110 actual = actual + "\\phantom{" + phantom + "}";
107 } 111 }
@@ -129,11 +133,12 @@ public class LatexFormulaExcelExporterUtil { @@ -129,11 +133,12 @@ public class LatexFormulaExcelExporterUtil {
129 return ""; 133 return "";
130 } 134 }
131 135
  136 + String referenceComponentLatex = resolveReferenceComponentLatex(componentList);
132 int missing = Math.max(0, 3 - nonNullCount); 137 int missing = Math.max(0, 3 - nonNullCount);
133 if (missing > 0) { 138 if (missing > 0) {
134 StringBuilder phantom = new StringBuilder(); 139 StringBuilder phantom = new StringBuilder();
135 for (int i = 0; i < missing; i++) { 140 for (int i = 0; i < missing; i++) {
136 - phantom.append("\\!\\times\\!000^{+00}_{+00}"); 141 + phantom.append("\\!\\times\\!").append(referenceComponentLatex);
137 } 142 }
138 actual = actual + "\\phantom{" + phantom + "}"; 143 actual = actual + "\\phantom{" + phantom + "}";
139 } 144 }
@@ -158,21 +163,45 @@ public class LatexFormulaExcelExporterUtil { @@ -158,21 +163,45 @@ public class LatexFormulaExcelExporterUtil {
158 latex.append(separator); 163 latex.append(separator);
159 } 164 }
160 first = false; 165 first = false;
  166 + latex.append(buildLatexComponent(comp));
  167 + }
  168 + return latex.toString();
  169 + }
161 170
162 - latex.append(formatScientificNotation(comp.getBase()));  
163 - if (comp.getSup() != null && comp.getSup().compareTo(BigDecimal.ZERO) >= 0) {  
164 - latex.append("^{+").append(formatScientificNotation(comp.getSup())).append("}"); 171 + private static String resolveReferenceComponentLatex(List<FormulaComponent> componentList) {
  172 + String reference = "000^{+00}_{+00}";
  173 + int maxLength = reference.length();
  174 + for (FormulaComponent comp : componentList) {
  175 + if (comp == null || comp.getBase() == null) {
  176 + continue;
165 } 177 }
166 - if (comp.getSup() != null && comp.getSup().compareTo(BigDecimal.ZERO) < 0) {  
167 - latex.append("^{").append(formatScientificNotation(comp.getSup())).append("}"); 178 + String candidate = buildLatexComponent(comp);
  179 + if (candidate.length() > maxLength) {
  180 + reference = candidate;
  181 + maxLength = candidate.length();
168 } 182 }
  183 + }
  184 + return reference;
  185 + }
169 186
170 - if (comp.getSub() != null && comp.getSub().compareTo(BigDecimal.ZERO) >= 0) {  
171 - latex.append("_{+").append(formatScientificNotation(comp.getSub())).append("}");  
172 - }  
173 - if (comp.getSub() != null && comp.getSub().compareTo(BigDecimal.ZERO) < 0) {  
174 - latex.append("_{").append(formatScientificNotation(comp.getSub())).append("}");  
175 - } 187 + private static String buildLatexComponent(FormulaComponent comp) {
  188 + if (comp == null || comp.getBase() == null) {
  189 + return "";
  190 + }
  191 + StringBuilder latex = new StringBuilder();
  192 + latex.append(formatScientificNotation(comp.getBase()));
  193 + if (comp.getSup() != null && comp.getSup().compareTo(BigDecimal.ZERO) >= 0) {
  194 + latex.append("^{+").append(formatScientificNotation(comp.getSup())).append("}");
  195 + }
  196 + if (comp.getSup() != null && comp.getSup().compareTo(BigDecimal.ZERO) < 0) {
  197 + latex.append("^{").append(formatScientificNotation(comp.getSup())).append("}");
  198 + }
  199 +
  200 + if (comp.getSub() != null && comp.getSub().compareTo(BigDecimal.ZERO) >= 0) {
  201 + latex.append("_{+").append(formatScientificNotation(comp.getSub())).append("}");
  202 + }
  203 + if (comp.getSub() != null && comp.getSub().compareTo(BigDecimal.ZERO) < 0) {
  204 + latex.append("_{").append(formatScientificNotation(comp.getSub())).append("}");
176 } 205 }
177 return latex.toString(); 206 return latex.toString();
178 } 207 }
@@ -295,6 +324,17 @@ public class LatexFormulaExcelExporterUtil { @@ -295,6 +324,17 @@ public class LatexFormulaExcelExporterUtil {
295 public static void insertContractLatexImageToCellFillTemplate(Workbook workbook, Sheet sheet, String latex, 324 public static void insertContractLatexImageToCellFillTemplate(Workbook workbook, Sheet sheet, String latex,
296 int rowIndex, int colIndex) throws IOException { 325 int rowIndex, int colIndex) throws IOException {
297 int baseFontSize = Math.max(16, resolveCellFontSize(workbook, sheet, rowIndex, colIndex)); 326 int baseFontSize = Math.max(16, resolveCellFontSize(workbook, sheet, rowIndex, colIndex));
  327 + insertContractLatexImageToCellFillTemplate(workbook, sheet, latex, rowIndex, colIndex, baseFontSize);
  328 + }
  329 +
  330 + public static void insertContractLatexImageToCellFillTemplate(Workbook workbook, Sheet sheet, String latex,
  331 + int rowIndex, int colIndex, int baseFontSize) throws IOException {
  332 + insertContractLatexImageToCellFillTemplate(workbook, sheet, latex, rowIndex, colIndex, baseFontSize, null);
  333 + }
  334 +
  335 + public static void insertContractLatexImageToCellFillTemplate(Workbook workbook, Sheet sheet, String latex,
  336 + int rowIndex, int colIndex, int baseFontSize,
  337 + Double maxScale) throws IOException {
298 CellRangeAddress mergedRegion = findMergedRegion(sheet, rowIndex, colIndex); 338 CellRangeAddress mergedRegion = findMergedRegion(sheet, rowIndex, colIndex);
299 if (mergedRegion != null) { 339 if (mergedRegion != null) {
300 insertContractLatexImageToRegionFillTemplate( 340 insertContractLatexImageToRegionFillTemplate(
@@ -305,11 +345,57 @@ public class LatexFormulaExcelExporterUtil { @@ -305,11 +345,57 @@ public class LatexFormulaExcelExporterUtil {
305 mergedRegion.getFirstColumn(), 345 mergedRegion.getFirstColumn(),
306 mergedRegion.getLastRow() - mergedRegion.getFirstRow() + 1, 346 mergedRegion.getLastRow() - mergedRegion.getFirstRow() + 1,
307 mergedRegion.getLastColumn() - mergedRegion.getFirstColumn() + 1, 347 mergedRegion.getLastColumn() - mergedRegion.getFirstColumn() + 1,
308 - baseFontSize 348 + baseFontSize,
  349 + maxScale
309 ); 350 );
310 return; 351 return;
311 } 352 }
312 - insertContractLatexImageToRegionFillTemplate(workbook, sheet, latex, rowIndex, colIndex, 1, 1, baseFontSize); 353 + insertContractLatexImageToRegionFillTemplate(workbook, sheet, latex, rowIndex, colIndex, 1, 1, baseFontSize, maxScale);
  354 + }
  355 +
  356 + public static int calculateContractBestFontSize(Workbook workbook, Sheet sheet, String latex,
  357 + int rowIndex, int colIndex) throws IOException {
  358 + int baseFontSize = Math.max(16, resolveCellFontSize(workbook, sheet, rowIndex, colIndex));
  359 + CellRangeAddress mergedRegion = findMergedRegion(sheet, rowIndex, colIndex);
  360 + if (mergedRegion != null) {
  361 + return calculateContractBestFontSizeForRegion(
  362 + sheet,
  363 + latex,
  364 + mergedRegion.getFirstRow(),
  365 + mergedRegion.getFirstColumn(),
  366 + mergedRegion.getLastRow() - mergedRegion.getFirstRow() + 1,
  367 + mergedRegion.getLastColumn() - mergedRegion.getFirstColumn() + 1,
  368 + baseFontSize
  369 + );
  370 + }
  371 + return calculateContractBestFontSizeForRegion(sheet, latex, rowIndex, colIndex, 1, 1, baseFontSize);
  372 + }
  373 +
  374 + public static int calculateContractReferenceFontSize(Workbook workbook, Sheet sheet,
  375 + int rowIndex, int colIndex) throws IOException {
  376 + return calculateContractBestFontSize(workbook, sheet, CONTRACT_SPEC_REFERENCE_LATEX, rowIndex, colIndex);
  377 + }
  378 +
  379 + public static double calculateContractFitScale(Workbook workbook, Sheet sheet, String latex,
  380 + int rowIndex, int colIndex, int fontSize) throws IOException {
  381 + CellRangeAddress mergedRegion = findMergedRegion(sheet, rowIndex, colIndex);
  382 + if (mergedRegion != null) {
  383 + return calculateContractFitScaleForRegion(
  384 + sheet,
  385 + latex,
  386 + mergedRegion.getFirstRow(),
  387 + mergedRegion.getFirstColumn(),
  388 + mergedRegion.getLastRow() - mergedRegion.getFirstRow() + 1,
  389 + mergedRegion.getLastColumn() - mergedRegion.getFirstColumn() + 1,
  390 + fontSize
  391 + );
  392 + }
  393 + return calculateContractFitScaleForRegion(sheet, latex, rowIndex, colIndex, 1, 1, fontSize);
  394 + }
  395 +
  396 + public static double calculateContractReferenceFitScale(Workbook workbook, Sheet sheet,
  397 + int rowIndex, int colIndex, int fontSize) throws IOException {
  398 + return calculateContractFitScale(workbook, sheet, CONTRACT_SPEC_REFERENCE_LATEX, rowIndex, colIndex, fontSize);
313 } 399 }
314 400
315 private static final int EMU_PER_PX = 9525; 401 private static final int EMU_PER_PX = 9525;
@@ -478,7 +564,7 @@ public class LatexFormulaExcelExporterUtil { @@ -478,7 +564,7 @@ public class LatexFormulaExcelExporterUtil {
478 564
479 private static void insertContractLatexImageToRegionFillTemplate(Workbook workbook, Sheet sheet, String latex, 565 private static void insertContractLatexImageToRegionFillTemplate(Workbook workbook, Sheet sheet, String latex,
480 int rowIndex, int colIndex, int rowRange, int colRange, 566 int rowIndex, int colIndex, int rowRange, int colRange,
481 - int baseFontSize) throws IOException { 567 + int baseFontSize, Double maxScale) throws IOException {
482 int regionWidthPx = 0; 568 int regionWidthPx = 0;
483 for (int c = colIndex; c < colIndex + colRange; c++) { 569 for (int c = colIndex; c < colIndex + colRange; c++) {
484 regionWidthPx += getColumnWidthPx(sheet, c); 570 regionWidthPx += getColumnWidthPx(sheet, c);
@@ -488,26 +574,29 @@ public class LatexFormulaExcelExporterUtil { @@ -488,26 +574,29 @@ public class LatexFormulaExcelExporterUtil {
488 regionHeightPx += getRowHeightPx(sheet, r); 574 regionHeightPx += getRowHeightPx(sheet, r);
489 } 575 }
490 576
491 - int paddingXPx = 4;  
492 - int paddingYPx = 2; 577 + int paddingXPx = 6;
  578 + int paddingYPx = 4;
493 int availableWidthPx = Math.max(1, regionWidthPx - paddingXPx * 2); 579 int availableWidthPx = Math.max(1, regionWidthPx - paddingXPx * 2);
494 int availableHeightPx = Math.max(1, regionHeightPx - paddingYPx * 2); 580 int availableHeightPx = Math.max(1, regionHeightPx - paddingYPx * 2);
495 - RenderedLatexImage renderedImage = renderBestFitLatexImageByHeight(  
496 - latex,  
497 - baseFontSize,  
498 - availableHeightPx  
499 - ); 581 + RenderedLatexImage renderedImage = renderLatexImage(latex, baseFontSize);
500 if (renderedImage.image == null) { 582 if (renderedImage.image == null) {
501 return; 583 return;
502 } 584 }
503 585
504 byte[] imageBytes = renderedImage.imageBytes; 586 byte[] imageBytes = renderedImage.imageBytes;
505 BufferedImage image = renderedImage.image; 587 BufferedImage image = renderedImage.image;
506 - int scaledHeightPx = availableHeightPx;  
507 - int widthByHeightPx = Math.max(1, (int) Math.round(  
508 - (double) image.getWidth() * scaledHeightPx / Math.max(1, image.getHeight())  
509 - ));  
510 - int scaledWidthPx = Math.min(availableWidthPx, widthByHeightPx); 588 + double scale = Math.min(
  589 + 1.0,
  590 + Math.min(
  591 + (double) availableWidthPx / Math.max(1, image.getWidth()),
  592 + (double) availableHeightPx / Math.max(1, image.getHeight())
  593 + )
  594 + );
  595 + if (maxScale != null) {
  596 + scale = Math.min(scale, maxScale);
  597 + }
  598 + int scaledWidthPx = Math.max(1, (int) Math.round(image.getWidth() * scale));
  599 + int scaledHeightPx = Math.max(1, (int) Math.round(image.getHeight() * scale));
511 600
512 int offsetXPx = Math.max(paddingXPx, (regionWidthPx - scaledWidthPx) / 2); 601 int offsetXPx = Math.max(paddingXPx, (regionWidthPx - scaledWidthPx) / 2);
513 int offsetYPx = Math.max(paddingYPx, (regionHeightPx - scaledHeightPx) / 2); 602 int offsetYPx = Math.max(paddingYPx, (regionHeightPx - scaledHeightPx) / 2);
@@ -566,6 +655,55 @@ public class LatexFormulaExcelExporterUtil { @@ -566,6 +655,55 @@ public class LatexFormulaExcelExporterUtil {
566 drawing.createPicture(anchor, pictureIdx); 655 drawing.createPicture(anchor, pictureIdx);
567 } 656 }
568 657
  658 + private static int calculateContractBestFontSizeForRegion(Sheet sheet, String latex,
  659 + int rowIndex, int colIndex, int rowRange, int colRange,
  660 + int preferredFontSize) throws IOException {
  661 + int regionWidthPx = 0;
  662 + for (int c = colIndex; c < colIndex + colRange; c++) {
  663 + regionWidthPx += getColumnWidthPx(sheet, c);
  664 + }
  665 + int regionHeightPx = 0;
  666 + for (int r = rowIndex; r < rowIndex + rowRange; r++) {
  667 + regionHeightPx += getRowHeightPx(sheet, r);
  668 + }
  669 +
  670 + int paddingXPx = 3;
  671 + int paddingYPx = 1;
  672 + int availableWidthPx = Math.max(1, regionWidthPx - paddingXPx * 2);
  673 + int availableHeightPx = Math.max(1, regionHeightPx - paddingYPx * 2);
  674 + return renderBestFitLatexFontSize(latex, preferredFontSize, availableWidthPx, availableHeightPx);
  675 + }
  676 +
  677 + private static double calculateContractFitScaleForRegion(Sheet sheet, String latex,
  678 + int rowIndex, int colIndex, int rowRange, int colRange,
  679 + int fontSize) throws IOException {
  680 + int regionWidthPx = 0;
  681 + for (int c = colIndex; c < colIndex + colRange; c++) {
  682 + regionWidthPx += getColumnWidthPx(sheet, c);
  683 + }
  684 + int regionHeightPx = 0;
  685 + for (int r = rowIndex; r < rowIndex + rowRange; r++) {
  686 + regionHeightPx += getRowHeightPx(sheet, r);
  687 + }
  688 +
  689 + int paddingXPx = 6;
  690 + int paddingYPx = 4;
  691 + int availableWidthPx = Math.max(1, regionWidthPx - paddingXPx * 2);
  692 + int availableHeightPx = Math.max(1, regionHeightPx - paddingYPx * 2);
  693 + RenderedLatexImage renderedImage = renderLatexImage(latex, fontSize);
  694 + if (renderedImage.image == null) {
  695 + return 1.0;
  696 + }
  697 +
  698 + return Math.min(
  699 + 1.0,
  700 + Math.min(
  701 + (double) availableWidthPx / Math.max(1, renderedImage.image.getWidth()),
  702 + (double) availableHeightPx / Math.max(1, renderedImage.image.getHeight())
  703 + )
  704 + );
  705 + }
  706 +
569 private static int getColumnWidthPx(Sheet sheet, int colIndex) { 707 private static int getColumnWidthPx(Sheet sheet, int colIndex) {
570 int widthUnits = sheet.getColumnWidth(colIndex); 708 int widthUnits = sheet.getColumnWidth(colIndex);
571 return Math.max(1, (int) Math.round(widthUnits / 256.0 * 7.0 + 5)); 709 return Math.max(1, (int) Math.round(widthUnits / 256.0 * 7.0 + 5));
@@ -577,26 +715,26 @@ public class LatexFormulaExcelExporterUtil { @@ -577,26 +715,26 @@ public class LatexFormulaExcelExporterUtil {
577 return Math.max(1, (int) Math.round(points * 96.0 / 72.0)); 715 return Math.max(1, (int) Math.round(points * 96.0 / 72.0));
578 } 716 }
579 717
580 - private static RenderedLatexImage renderBestFitLatexImageByHeight(String latex, int preferredFontSize,  
581 - int targetHeightPx) throws IOException { 718 + private static int renderBestFitLatexFontSize(String latex, int preferredFontSize,
  719 + int targetWidthPx, int targetHeightPx) throws IOException {
582 int minFontSize = 8; 720 int minFontSize = 8;
583 int maxFontSize = Math.max(minFontSize, preferredFontSize + 40); 721 int maxFontSize = Math.max(minFontSize, preferredFontSize + 40);
584 maxFontSize = Math.min(96, maxFontSize); 722 maxFontSize = Math.min(96, maxFontSize);
585 int left = minFontSize; 723 int left = minFontSize;
586 int right = maxFontSize; 724 int right = maxFontSize;
587 - RenderedLatexImage best = renderLatexImage(latex, minFontSize); 725 + int bestFontSize = minFontSize;
588 726
589 while (left <= right) { 727 while (left <= right) {
590 int mid = (left + right) >>> 1; 728 int mid = (left + right) >>> 1;
591 RenderedLatexImage candidate = renderLatexImage(latex, mid); 729 RenderedLatexImage candidate = renderLatexImage(latex, mid);
592 - if (candidate.image != null && candidate.image.getHeight() <= targetHeightPx) {  
593 - best = candidate; 730 + if (fitsWithin(candidate, targetWidthPx, targetHeightPx)) {
  731 + bestFontSize = mid;
594 left = mid + 1; 732 left = mid + 1;
595 } else { 733 } else {
596 right = mid - 1; 734 right = mid - 1;
597 } 735 }
598 } 736 }
599 - return best; 737 + return bestFontSize;
600 } 738 }
601 739
602 private static RenderedLatexImage renderLatexImage(String latex, int fontSize) throws IOException { 740 private static RenderedLatexImage renderLatexImage(String latex, int fontSize) throws IOException {
@@ -659,6 +797,13 @@ public class LatexFormulaExcelExporterUtil { @@ -659,6 +797,13 @@ public class LatexFormulaExcelExporterUtil {
659 } 797 }
660 } 798 }
661 799
  800 + private static boolean fitsWithin(RenderedLatexImage renderedImage, int targetWidthPx, int targetHeightPx) {
  801 + return renderedImage != null
  802 + && renderedImage.image != null
  803 + && renderedImage.image.getWidth() <= targetWidthPx
  804 + && renderedImage.image.getHeight() <= targetHeightPx;
  805 + }
  806 +
662 private static BufferedImage trimWhitespace(BufferedImage source, int whiteThreshold, int marginPx) { 807 private static BufferedImage trimWhitespace(BufferedImage source, int whiteThreshold, int marginPx) {
663 if (source == null || source.getWidth() <= 0 || source.getHeight() <= 0) { 808 if (source == null || source.getWidth() <= 0 || source.getHeight() <= 0) {
664 return source; 809 return source;