惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LangChain Blog
V
V2EX
爱范儿
爱范儿
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Martin Fowler
Martin Fowler
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Apple Machine Learning Research
Apple Machine Learning Research
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
罗磊的独立博客
小众软件
小众软件
Vercel News
Vercel News
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
V
Visual Studio Blog
J
Java Code Geeks
P
Proofpoint News Feed
MongoDB | Blog
MongoDB | Blog
B
Blog
美团技术团队
量子位

博客园 - 三颗纽扣

windows下安装redmine-2.1 try-cache-finally 在线程被杀掉时还有作用吗? 使用InfoBright实现20-100亿条原始话单记录的检索 Hibernate乐观锁真的会抛出异常吗? 并非文学化编程,在VS环境下的折中方案 快速复制NuGet引用 语义版本规范 基础框架的基础组件 在 IIS 6 上架设 NuGet Server DotNet开发利器之MyEclipseShortcuts 我们是原始生物 没有别的,只有天使 灯是用来照亮的,而不是引路的 戒了,过去完成时 我送给你们的,没有别的——只有天使。 Builder 链——另类一点的Builder模式 多线程JUnit单元测试:GroboUtils and ConTest 控制内存的使用之二:对象缓存 pool and cache 控制内存的使用
通过 POI 获取图片在 Excel 表格中的位置
三颗纽扣 · 2010-09-13 · via 博客园 - 三颗纽扣

POI 目前的版本,只提供了获取 Excel 表格中图片内容的方法(workbook.getAllPictures),但无法通过这个方法获得每个图片所在的位置,通过直接深入 Excel Record 数据,其实可以取出 Excel 表格每个内嵌对象的位置信息(ClientAnchorInfo),可惜位置信息中又不包含图片内容,所以,只能简单的假定,这两个方法所返回的列表,应该是一一对应的,通过这个假定,或许可以成功取到每个图片的位置信息,既其中心点所在的单元格。直接的应用之一,就是在导入人员等信息时,可以导入照片。

上代码:

获取位置

    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();
    }
    
}