转:通过 POI 获取图片在 Excel 表格中的位置

 静态报表真的很头痛哦,查找很久发现JXL、POI在读取excel中自制的统计图表方面存在局限,无法读取;但在读取一张图片以及写入图表方面还可以,我的问题解决不了了,肿么办??????

 

java如何读取excel中自制的统计图表,然后将读到的图表生成 png格式的图片???

注:图表可能是一个完整的模板,也可能是通过excel中多个图表工具组合成的复合图表

 

希望能帮我的朋友给我发邮件,提供解决方法,不胜感激!邮箱:a303313655@163.com

 

在网站查找中发现通过POI获取图片在excel中的位置的博客,觉得思路很好,现转载一下,大家分享!

转载地址:http://www.cnblogs.com/shwen99/archive/2010/09/13/1824896.html

 

 获取位置:

public static List<MyPictureData> getAllPictures(HSSFWorkbook workbook) {
        List<MyPictureData> list = new ArrayList<MyPictureData>();

        List<HSSFPictureData> pictureList = workbook.getAllPictures();
        List<ClientAnchorInfo> clientAnchorRecords = getClientAnchorRecords(workbook);
        
        if (pictureList.size() != clientAnchorRecords.size()) {
            throw new RuntimeException("解析文件中的图片信息出错,找到的图片数量和图片位置信息数量不匹配");
        }
        
        for (int i = 0; i < pictureList.size(); i++) {
            HSSFPictureData pictureData = pictureList.get(i);
            ClientAnchorInfo anchor = clientAnchorRecords.get(i);
            HSSFSheet sheet = anchor.sheet;
            EscherClientAnchorRecord clientAnchorRecord = anchor.clientAnchorRecord;
            list.add(new MyPictureData(workbook, sheet, pictureData, clientAnchorRecord));
        }
        
        return list ;
    }

    private static class ClientAnchorInfo {
        public HSSFSheet sheet;
        public EscherClientAnchorRecord clientAnchorRecord;
        
        public ClientAnchorInfo(HSSFSheet sheet, EscherClientAnchorRecord clientAnchorRecord) {
            super();
            this.sheet = sheet;
            this.clientAnchorRecord = clientAnchorRecord;
        }
    }
    private static List<ClientAnchorInfo> getClientAnchorRecords(HSSFWorkbook workbook) {
        List<ClientAnchorInfo> list = new ArrayList<ClientAnchorInfo>();
        
        EscherAggregate drawingAggregate = null;
        HSSFSheet sheet = null;
        List<EscherRecord> recordList = null;
        Iterator<EscherRecord> recordIter = null;
        int numSheets = workbook.getNumberOfSheets();
        for(int i = 0; i < numSheets; i++) {
            sheet = workbook.getSheetAt(i);
            drawingAggregate = sheet.getDrawingEscherAggregate();
            if(drawingAggregate != null) {
                recordList = drawingAggregate.getEscherRecords();
                recordIter = recordList.iterator();
                while(recordIter.hasNext()) {
                    getClientAnchorRecords(sheet, recordIter.next(), 1, list);
                }
            }
        }
        
        return list;
    }

    private static void getClientAnchorRecords(HSSFSheet sheet, EscherRecord escherRecord, int level, List<ClientAnchorInfo> list) {
        List<EscherRecord> recordList = null;
        Iterator<EscherRecord> recordIter = null;
        EscherRecord childRecord = null;
        recordList = escherRecord.getChildRecords();
        recordIter = recordList.iterator();
        while(recordIter.hasNext()) {
            childRecord = recordIter.next();
            if(childRecord instanceof EscherClientAnchorRecord) {
                ClientAnchorInfo e = new ClientAnchorInfo(sheet, (EscherClientAnchorRecord) childRecord);
                list.add(e);
            }
            if(childRecord.getChildRecords().size() > 0) {
                getClientAnchorRecords(sheet, childRecord, level+1, list);
            }
        }
    }


相关类,计算中心位置:

package com.ultrapower.imonitor.emcc.dao.utils;

import org.apache.poi.ddf.EscherClientAnchorRecord;
import org.apache.poi.hssf.usermodel.HSSFPictureData;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class MyPictureData {
    private final HSSFWorkbook workbook;
    private final HSSFSheet sheet;
    private final HSSFPictureData pictureData;
    private final EscherClientAnchorRecord clientAnchor;
    
    public MyPictureData(HSSFWorkbook workbook, HSSFSheet sheet, HSSFPictureData pictureData, EscherClientAnchorRecord clientAnchor) {
        this.workbook = workbook;
        this.sheet = sheet;
        this.pictureData = pictureData;
        this.clientAnchor = clientAnchor;
    }
    
    public HSSFWorkbook getWorkbook() {
        return workbook;
    }
    
    public HSSFSheet getSheet() {
        return sheet;
    }
    
    public EscherClientAnchorRecord getClientAnchor() {
        return clientAnchor;
    }
    
    public HSSFPictureData getPictureData() {
        return pictureData;
    }

    public byte[] getData() {
        return pictureData.getData();
    }

    public String suggestFileExtension() {
        return pictureData.suggestFileExtension();
    }
    
    /**
     * 推测图片中心所覆盖的单元格,这个值不一定准确,但通常有效
     * 
     * @return the row0
     */
    public short getRow0() {
        int row1 = getRow1();
        int row2 = getRow2();
        if (row1 == row2) {
            return (short) row1;
        }
        
        int heights[] = new int[row2-row1+1];
        for (int i = 0; i < heights.length; i++) {
            heights[i] = getRowHeight(row1 + i);
        }
        
        // HSSFClientAnchor 中 dx 只能在 0-1023 之间,dy 只能在 0-255 之间
        // 表示相对位置的比率,不是绝对值
        int dy1 = getDy1() * heights[0] / 255;
        int dy2 = getDy2() * heights[heights.length-1] / 255;
        return (short) (getCenter(heights, dy1, dy2) + row1);
    }
    
    
    private short getRowHeight(int rowIndex) {
        HSSFRow row = sheet.getRow(rowIndex);
        short h = row == null? sheet.getDefaultRowHeight() : row.getHeight();
        return h;
    }
    
    /**
     * 推测图片中心所覆盖的单元格,这个值不一定准确,但通常有效
     * 
     * @return the col0
     */
    public short getCol0() {
        short col1 = getCol1();
        short col2 = getCol2();
        
        if (col1 == col2) {
            return col1;
        }
        
        int widths[] = new int[col2-col1+1];
        for (int i = 0; i < widths.length; i++) {
            widths[i] = sheet.getColumnWidth(col1 + i);
        }
        
        // HSSFClientAnchor 中 dx 只能在 0-1023 之间,dy 只能在 0-255 之间
        // 表示相对位置的比率,不是绝对值
        int dx1 = getDx1() * widths[0] / 1023;
        int dx2 = getDx2() * widths[widths.length-1] / 1023;

        return (short) (getCenter(widths, dx1, dx2) + col1);
    }
    
    /**
     * 给定各线段的长度,以及起点相对于起点段的偏移量,终点相对于终点段的偏移量,
     * 求中心点所在的线段
     * 
     * @param a the a 各线段的长度
     * @param d1 the d1 起点相对于起点段
     * @param d2 the d2 终点相对于终点段的偏移量
     * 
     * @return the center
     */
    protected static int getCenter(int[] a, int d1, int d2) {
        // 线段长度
        int width = a[0] - d1 + d2;
        for (int i = 1; i < a.length-1; i++) {
            width += a[i];
        }

        // 中心点位置
        int c = width / 2 + d1;
        int x = a[0];
        int cno = 0;
        
        while (c > x) {
            x += a[cno];
            cno++;
        }
        
        return cno;
    }

    /**
     * 左上角所在列
     * 
     * @return the col1
     */
    public short getCol1() {
        return clientAnchor.getCol1();
    }

    /**
     * 右下角所在的列
     * 
     * @return the col2
     */
    public short getCol2() {
        return clientAnchor.getCol2();
    }

    /**
     * 左上角的相对偏移量
     * 
     * @return the dx1
     */
    public short getDx1() {
        return clientAnchor.getDx1();
    }

    /**
     * 右下角的相对偏移量
     * 
     * @return the dx2
     */
    public short getDx2() {
        return clientAnchor.getDx2();
    }

    /**
     * 左上角的相对偏移量
     * 
     * @return the dy1
     */
    public short getDy1() {
        return clientAnchor.getDy1();
    }

    /**
     * 右下角的相对偏移量
     * 
     * @return the dy2
     */
    public short getDy2() {
        return clientAnchor.getDy2();
    }

    /**
     * 左上角所在的行
     * 
     * @return the row1
     */
    public short getRow1() {
        return clientAnchor.getRow1();
    }

    /**
     * 右下角所在的行
     * 
     * @return the row2
     */
    public short getRow2() {
        return clientAnchor.getRow2();
    }
    
}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值