[alibaba/easyexcel]合并单元格填充多个图片时,图片的左边距不能跨过第一个单元格的右侧

2023-12-14 460 views
6

需求: 将合并的单元格里,用图片方式显示复选框 image

我发现,在合并单元格里,当左边距超过第一个单元格的宽度时,就没有效果了,图片的左侧一直停留在单元格右侧边框上 image

实际显示效果: 图片1.位置设置:

            imageData.setLeft(8);
            imageData.setTop(3);
            imageData.setRight(528);
            imageData.setBottom(43);

图片2.位置设置:

            imageData.setLeft(100);
            imageData.setTop(2);
            imageData.setRight(490);
            imageData.setBottom(40);

图片3.位置设置:

            imageData.setLeft(200);
            imageData.setTop(20);
            imageData.setRight(490);
            imageData.setBottom(10);

测试

代码: easyexcel版本:3.2.0

    @Test
    public void writeRLJX()  throws Exception
    {

        //
        String filePath = "C:\\ecloud\\uploadPath\\download";
        String templateName = filePath + File.separator + "demo\\jxrl.workdoc.xlsx";
        String fileName = filePath + File.separator + "demo\\测试" + ".xlsx";
        // 图片路径
        String imagePath = filePath + File.separator  + "demo\\checkbox.png";
        String imagePath2 = filePath + File.separator  + "demo\\danger.png";
        String imagePath3 = filePath + File.separator  + "demo\\profile.jpg";

        ExcelWriter excelWriter = null;
        try {
            // 1. 创建一个工作薄对象 ExcelWriter == workbook
            excelWriter = EasyExcel.write(fileName)
                     .withTemplate(templateName)
                    .build();

            // 2. 创建一个工作表对象
            WriteSheet sheet = EasyExcel.writerSheet().build();

            // 3. 数据
            HashMap<String, Object> data = new HashMap<String, Object>();

            File file = new File(imagePath);

            WriteCellData<Void> writeCellData = new WriteCellData<>();

            // 这里演示
            // 可以放入多个图片
            List<ImageData> imageDataList = new ArrayList<>();

            // 1. 放入第一个图片
            // .1.1 创建一个新的ImageData对象
            ImageData imageData = new ImageData();
            // .1.2 将ImageData对象加入链表List<ImageData>
            imageDataList.add(imageData);
            // .1.2 将List<ImageData>加入到WriteCellData
            writeCellData.setImageDataList(imageDataList);

            // .2.1 放入二进制进制图片
            imageData.setImage(FileUtils.readFileToByteArray(new File(imagePath)));
            // .2.2 图片类型
            imageData.setImageType(ImageData.ImageType.PICTURE_TYPE_PNG);
            // .2.3 上 右 下 左 需要留空
            // 这个类似于 css 的 margin
            // 这里实测 不能设置太大 超过单元格原始大小后 打开会提示修复。暂时未找到很好的解法。
            imageData.setLeft(8);
            imageData.setTop(3);
            imageData.setRight(528);
            imageData.setBottom(43);

            imageData.setRelativeFirstRowIndex(0);
            imageData.setRelativeFirstColumnIndex(0);
            imageData.setRelativeLastRowIndex(0);
            imageData.setRelativeLastColumnIndex(11);

            // 2. 放入第二个图片
            imageData = new ImageData();
            imageDataList.add(imageData);
            writeCellData.setImageDataList(imageDataList);

            imageData.setImage(FileUtils.readFileToByteArray(new File(imagePath2)));
            imageData.setImageType(ImageData.ImageType.PICTURE_TYPE_PNG);
            imageData.setLeft(100);
            imageData.setTop(2);
            imageData.setRight(490);
            imageData.setBottom(40);

            imageData.setRelativeFirstRowIndex(0);
            imageData.setRelativeFirstColumnIndex(0);
            imageData.setRelativeLastRowIndex(0);
            imageData.setRelativeLastColumnIndex(11);

            // 3. 放入第三个图片
            imageData = new ImageData();
            imageDataList.add(imageData);
            writeCellData.setImageDataList(imageDataList);

            imageData.setImage(FileUtils.readFileToByteArray(new File(imagePath3)));
            imageData.setImageType(ImageData.ImageType.PICTURE_TYPE_PNG);
            imageData.setLeft(200);           
             imageData.setTop(20);
            imageData.setRight(490);
            imageData.setBottom(10);

            imageData.setRelativeFirstRowIndex(0);
            imageData.setRelativeFirstColumnIndex(0);
            imageData.setRelativeLastRowIndex(0);
            imageData.setRelativeLastColumnIndex(11);

            writeCellData.setType(CellDataTypeEnum.STRING);
            writeCellData.setStringValue(" □企业级      □部门级      □班组级      ■岗位级");

            // 3.3 填充数据
            data.put("image2", writeCellData);
            excelWriter.fill(data, sheet);

            // 4. 关闭流
            excelWriter.finish();
        }finally {
            // 千万别忘记close 会帮忙关闭流
            if (excelWriter != null) {
                excelWriter.close();
            }
        }

    }

请问,大家有什么好的办法?

回答

6

你想达到一个什么样的目的呢? 让图片自动填满吗,那可能你需要自己调整单元格大小 自动适配不太靠谱。

6

因为常规字库中如下的没有复选符号。我初步的想法,是通过复选图片来实现复选功能,把一个复选图片贴到对应选中的文本上,实现复选效果。因为涉及到多个不同的复选选项组(因为excel里不好排版,所以想在一个合并单元格里在对应文本位置填充多个复选图片,来实现复选效果)。 但在合并单元格里用图片填充时,发现图片的定位有问题——图片的左边距是不能超过合并单元格内包含的第一个单元格的右边距的。 image image 如上图,我期望将图片2移到部门级前,图片2的的左边距>cell(11,1)的列宽【上图红线标识处】,图片2的左边距并没有象我期望的移到位置 不知道大佬有何好的方案,希望指点一二!

9

如果能加字库是最好的解决办法。 我刚才查了下chatgpt 直接用poi生成复选框 他了给我一段代码,但是我自己测试我没有这个库,反正我用不了。。。 只能给你做参考用了

// 创建一个新的工作簿
XSSFWorkbook workbook = new XSSFWorkbook();

// 创建一个新的工作表
XSSFSheet sheet = workbook.createSheet("Sheet1");

// 创建一个新行
XSSFRow row = sheet.createRow(0);

// 创建一个新单元格
XSSFCell cell = row.createCell(0);

// 创建一个锚点
XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 0, 0, 1, 1);

// 创建一个简单形状,类型为复选框
XSSFDrawing drawing = sheet.createDrawingPatriarch();
XSSFSimpleShape checkbox = drawing.createSimpleShape(anchor);
checkbox.setShapeType(FormType.CHECK_BOX);

// 将复选框设置为选中状态
checkbox.getCTShape().getOleObject().setObjectData(new byte[]{0x01});

// 将工作簿写入文件
FileOutputStream out = new FileOutputStream(new File("workbook.xlsx"));
workbook.write(out);
out.close();
4

不知道您是否已经解决该问题?我们先暂时关闭这个问题,如果还存在问题请重新Reopen这个issue