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

推荐订阅源

博客园_首页
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Proofpoint News Feed
G
Google Developers Blog
B
Blog
Engineering at Meta
Engineering at Meta
阮一峰的网络日志
阮一峰的网络日志
The Register - Security
The Register - Security
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 叶小钗
The Cloudflare Blog
The Hacker News
The Hacker News
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
雷峰网
雷峰网
F
Fortinet All Blogs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Hackread – Cybersecurity News, Data Breaches, AI and More
酷 壳 – CoolShell
酷 壳 – CoolShell
Last Week in AI
Last Week in AI
T
Threat Research - Cisco Blogs
A
About on SuperTechFans
量子位
Recorded Future
Recorded Future
博客园 - 三生石上(FineUI控件)
H
Help Net Security
Help Net Security
Help Net Security
P
Palo Alto Networks Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Troy Hunt's Blog
W
WeLiveSecurity
V
Vulnerabilities – Threatpost
T
The Exploit Database - CXSecurity.com
Know Your Adversary
Know Your Adversary
Apple Machine Learning Research
Apple Machine Learning Research
Scott Helme
Scott Helme
N
News | PayPal Newsroom
AWS News Blog
AWS News Blog
D
DataBreaches.Net
Blog — PlanetScale
Blog — PlanetScale
MongoDB | Blog
MongoDB | Blog
B
Blog RSS Feed
腾讯CDC
J
Java Code Geeks
Microsoft Azure Blog
Microsoft Azure Blog
TaoSecurity Blog
TaoSecurity Blog
GbyAI
GbyAI
Y
Y Combinator Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
D
Docker

博客园 - 三颗纽扣

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