找回密码
 立即注册

QQ登录

只需一步,快速开始

xujie-joe
金牌服务用户   /  发表于:2022-11-3 14:50  /   查看:3095  /  回复:11
1金币

问题1:
后端GCExcel的Excel转PDF的功能,在转化过程中,有些单元格内容较多,被遮挡部分,显示不全

如下图
image.png406567992.png

ssjson如附件

代码如下:

public byte[] excelToPdf(String excelContent) {
        Workbook workbook = new Workbook();
        workbook.fromJson(excelContent);

        IWorksheets worksheets = workbook.getWorksheets();

        // 不同的模板所打印的区域不同
        // 获取Excel需要转PDF的列的范围
        String pdfArea = this.getTemplatePDFArea(worksheets);

        for (IWorksheet worksheet : worksheets) {
            // 设置字体为12号字体
            worksheet.getUsedRange().getFont().setSize(12d);

            // 设置Excel转PDF列的范围
             worksheet.getPageSetup().setPrintArea(pdfArea);

             // 以下属性的设置,可以让Excel转为PDF的时候所有列不换页
            worksheet.getPageSetup().setIsPercentScale(false);
//             worksheet.getPageSetup().setFitToPagesTall(1);
            worksheet.getPageSetup().setFitToPagesWide(1);

            // Set bestFitColumns/bestFitRows as true.
//             worksheet.getPageSetup().setBestFitColumns(true);
//            // 生成的PDF自适应行高
//             worksheet.getPageSetup().setBestFitRows(true);

//            worksheet.getUsedRange().autoFit(true);
            worksheet.getUsedRange().setWrapText(true);
//            worksheet.getUsedRange().getColumns().autoFit(true);
//            worksheet.getUsedRange().getRows().autoFit(true);
            worksheet.getRows().autoFit(true);

             // 上下左右各10边距
            worksheet.getPageSetup().setLeftMargin(15);
            worksheet.getPageSetup().setTopMargin(15);
            worksheet.getPageSetup().setRightMargin(15);
            worksheet.getPageSetup().setBottomMargin(15);

            // 都设置为A4纸
            worksheet.getPageSetup().setPaperSize(PaperSize.A4);
            // 竖向生成
            worksheet.getPageSetup().setOrientation(PageOrientation.Portrait);

            // 设置页脚的页数
            worksheet.getPageSetup().setCenterFooter("&P/&N");

            //Add page break
            // TODO 待开发20行一页PDF
//            worksheet.getHPageBreaks().add(worksheet.getRange("B3"));
//            worksheet.getVPageBreaks().add(worksheet.getRange("B3"));
        }
        // 再转为PDF
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        workbook.save(out, SaveFileFormat.Pdf);
        byte[] contents = out.toByteArray();
        return contents;
    }


worksheet.getRows().autoFit(true);这行代码大部分单元格生效了,但是如上有个单元格没生效,怀疑是两行单元格合并单元格导致的,帮忙看下。


问题2:
如上代码中: worksheet.getUsedRange().getFont().setSize(12d);
如果改为 worksheet.getUsedRange().getFont().setSize(16d);
会导致基本所有单元格都会遮挡,不能调字体大小吗,调了字体大小后,worksheet.getRows().autoFit(true);就不生效了
image.png90425414.png


image.png586241149.png

gongyi.zip

41.29 KB, 下载次数: 175

最佳答案

查看完整内容

请参考附件demo,主要代码如下: 效果如下:

11 个回复

倒序浏览
最佳答案
最佳答案
Lynn.Dou讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2022-11-3 14:50:38
来自 10#
请参考附件demo,主要代码如下:

  1. //  遍历获取所有合并单元格
  2.             int rowCount = worksheet.getRowCount();
  3.             int columnCount = worksheet.getColumnCount();
  4.             for (int r = 0; r < rowCount; r++) {
  5.                 for (int c = 0; c < columnCount; c++) {
  6.                     IRange range = worksheet.getRange(r, c);
  7.                     // 判断单元格是否在合并单元格区域内
  8.                     if (range.getMergeCells()) {
  9.                         // 获取合并单元格区域
  10.                         // range.getMergeArea();
  11.                         IRange mergeArea = range.getMergeArea();
  12.                         Double rowHeight = autoFitMergedCells(newWorksheet, mergeArea);
  13.                         if (rowHeight > range.getRowHeight()) {
  14.                             range.setRowHeight(rowHeight);
  15.                         }
  16.                     }

  17.                 }
  18.             }

  19.         }
  20.         // 删除新增sheet
  21.         workbook.getWorksheets().get(workbook.getWorksheets().getCount() - 1).delete();
复制代码

  1. public static Double autoFitMergedCells(IWorksheet newWorksheet, IRange mergedcell) {
  2.         // 获取合并单元格的列宽 和 value
  3.         Object value = mergedcell.getValue();
  4.         Double width = mergedcell.getWidthInPixel();

  5.         IRange range = newWorksheet.getRange(mergedcell.getRow(), mergedcell.getColumn());
  6.         // 给新建sheet中非合并单元格设置列宽和value
  7.         range.setValue(value);
  8.         range.setColumnWidthInPixel(width);

  9.         //  设置自适应行高,获取新行高,并返回
  10.         range.setWrapText(true);
  11.         range.autoFit();
  12.         return range.getRowHeight();
  13.     }
复制代码


效果如下:
image.png587026671.png

mergeCell_autofit_maven.zip

217.14 KB, 下载次数: 157

回复 使用道具 举报
xujie-joe
金牌服务用户   /  发表于:2022-11-3 15:13:40
2#
代码中:String pdfArea = this.getTemplatePDFArea(worksheets);
返回的结果是:
"$AI"
回复 使用道具 举报
xujie-joe
金牌服务用户   /  发表于:2022-11-3 15:14:16
3#
xujie-joe 发表于 2022-11-3 15:13
代码中:String pdfArea = this.getTemplatePDFArea(worksheets);
返回的结果是:
"$AI"

A到I列
回复 使用道具 举报
Lynn.Dou讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2022-11-3 17:22:56
4#
问题收到,这边先尝试复现下此问题,有结果贴中回复您。
回复 使用道具 举报
Lynn.Dou讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2022-11-3 17:55:02
5#
本帖最后由 Lynn.Dou 于 2022-11-14 16:28 编辑

您好,

问题1:
此问题属于产品设计,对于合并单元格不支持设置自适应行高,这一点也是与Excel一致的,您可以在Excel实际测试下。
有个思路您可以参考下:
新建一个sheet,将当前的合并单元格内容拷贝到新sheet中的非合并单元格(宽度和合并单元格相同),然后进行autofit,
用获取的行高赋值给原来的合并单元格所在行(如您截图中合并单元格为两行,您可以根据需要将新增行高赋值给其中一行,或者平均分配),

最后删除新增的sheet即可。


问题2:
关于问题2,注意到您另开了新帖,后续在新帖中交流跟进:
https://gcdn.grapecity.com.cn/fo ... 9&fromuid=59119


回复 使用道具 举报
xujie-joe
金牌服务用户   /  发表于:2022-11-4 08:30:36
6#

好的,那问题1我只能一行行,对每个单元格拷贝到新sheet单元格中进行autofit,
然后取最大的行高,设置给原sheet那一行的行高了

或者说有什么方法可以判断某个单元格是合并单元格的,我只对合并单元格的进行处理,其它的单元格都自动autofit
回复 使用道具 举报
xujie-joe
金牌服务用户   /  发表于:2022-11-4 09:14:32
7#

按照您的思路,我对每个单元格计算了高度,没生效,代码是哪里有问题吗?
// 一行行,一个个单元格计算高度,取最大值
            int rowCount = worksheet.getRowCount();
            int columnCount = worksheet.getColumnCount();
            for (int i = 0; i < rowCount; i++) {
                // 初始的高度
                double height = worksheet.getRange(i, 0).getHeight();
                // 初始的宽度
                double width = worksheet.getRange(i, 0).getWidth();
                if (width < 0 || width > 255) {
                    continue;
                }
                for (int i1 = 0; i1 < columnCount; i1++) {
                    String text = worksheet.getRange(i, i1).getText();
                    if (StringUtils.isNotEmpty(text)) {
                        forCalculateSheet.getRange(0, 0).setValue(text);
                        forCalculateSheet.getRange(0, 0).setColumnWidth(width);
                        forCalculateSheet.getRange(0, 0).setWrapText(true);
                        forCalculateSheet.getRange(0, 0).autoFit();
                        double calculateHeight = forCalculateSheet.getRange(0, 0).getHeight();
                        height = height > calculateHeight ? height : calculateHeight;
                    }
                }
                worksheet.getRange(i, 0).getRows().setWrapText(true);
                worksheet.getRange(i, 0).getRows().setRowHeight(height);
            }


forCalculateSheet 是
// 用于计算单元格高度
        IWorksheet forCalculateSheet = worksheets.add();
回复 使用道具 举报
xujie-joe
金牌服务用户   /  发表于:2022-11-4 09:15:10
8#
如图
image.png222846373.png
回复 使用道具 举报
Lynn.Dou讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2022-11-4 11:47:45
9#
这边调研下实现代码,有结果贴中回复您。
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 立即注册
返回顶部