当前位置:网站首页>POI library update excel picture
POI library update excel picture
2022-06-12 08:44:00 【qluka】
Updating pictures includes deleting old pictures , New picture insert .
however , Go to POI Of API When you look for relevant content inside , It's only easier to find a way to add pictures , It's hard to find a way to delete pictures . And there are few related deletions on the Internet , Searching for a long time , from Stack Overflow Found a more reliable method on , as follows :
public static void deleteCTAnchor(XSSFPicture xssfPicture) {
XSSFDrawing drawing = xssfPicture.getDrawing();
XmlCursor cursor = xssfPicture.getCTPicture().newCursor();
cursor.toParent();
if (cursor.getObject() instanceof org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor) {
for (int i = 0; i < drawing.getCTDrawing().getTwoCellAnchorList().size(); i++) {
if (cursor.getObject().equals(drawing.getCTDrawing().getTwoCellAnchorArray(i))) {
drawing.getCTDrawing().removeTwoCellAnchor(i);
System.out.println("TwoCellAnchor for picture " + xssfPicture + " was deleted.");
}
}
} else if (cursor.getObject() instanceof org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTOneCellAnchor) {
for (int i = 0; i < drawing.getCTDrawing().getOneCellAnchorList().size(); i++) {
if (cursor.getObject().equals(drawing.getCTDrawing().getOneCellAnchorArray(i))) {
drawing.getCTDrawing().removeOneCellAnchor(i);
System.out.println("OneCellAnchor for picture " + xssfPicture + " was deleted.");
}
}
} else if (cursor.getObject() instanceof org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTAbsoluteAnchor) {
for (int i = 0; i < drawing.getCTDrawing().getAbsoluteAnchorList().size(); i++) {
if (cursor.getObject().equals(drawing.getCTDrawing().getAbsoluteAnchorArray(i))) {
drawing.getCTDrawing().removeAbsoluteAnchor(i);
System.out.println("AbsoluteAnchor for picture " + xssfPicture + " was deleted.");
}
}
}
}
public static void deleteEmbeddedXSSFPicture(XSSFPicture xssfPicture) {
if (xssfPicture.getCTPicture().getBlipFill() != null) {
if (xssfPicture.getCTPicture().getBlipFill().getBlip() != null) {
if (xssfPicture.getCTPicture().getBlipFill().getBlip().getEmbed() != null) {
String rId = xssfPicture.getCTPicture().getBlipFill().getBlip().getEmbed();
XSSFDrawing drawing = xssfPicture.getDrawing();
drawing.getPackagePart().removeRelationship(rId);
drawing.getPackagePart().getPackage().deletePartRecursive(drawing.getRelationById(rId).getPackagePart().getPartName());
System.out.println("Picture " + xssfPicture + " was deleted.");
}
}
}
}
public static void deleteHSSFShape(HSSFShape shape) {
HSSFPatriarch drawing = shape.getPatriarch();
drawing.removeShape(shape);
System.out.println("Shape " + shape + " was deleted.");
}
The author says , If you want to delete .xlsx The photos in , Need to delete its relations and anchor, And it's used poi 4.0.1 Test done
But my side is Android The project does not use 4.0.1 Version of , I'm using 3.9 Version of the library and related jar, The operation is also .xlsx Format . When relevant methods are adopted , It's a mistake , First, some classes and methods cannot be found , This can be commented out first , After testing , It's really not used . There are other methods in operation , That's what makes a mistake , Also, the relevant classes used cannot be found . Through source code comparison , Found the corresponding alternative method . The modified , In fact, the main revision is deleteCTAnchor The method inside , The modified method is as follows :
public static void deleteCTAnchor(XSSFPicture xssfPicture) {
XSSFDrawing drawing = xssfPicture.getDrawing();
XmlCursor cursor = xssfPicture.getCTPicture().newCursor();
cursor.toParent();
if (cursor.getObject() instanceof org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor) {
int len = drawing.getCTDrawing().getTwoCellAnchorArray().length;
int seleIn = -1;
for (int i = 0; i < len; i++) {
if (cursor.getObject().equals(drawing.getCTDrawing().getTwoCellAnchorArray(i))) {
seleIn = i;
System.out.println("TwoCellAnchor for picture " + xssfPicture + " was deleted.seleIn:" + i);
break;
}
}
if (seleIn != -1) {
drawing.getCTDrawing().removeTwoCellAnchor(seleIn);
}
} else if (cursor.getObject() instanceof org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTOneCellAnchor) {
int len = drawing.getCTDrawing().getOneCellAnchorArray().length;
int seleIn = -1;
for (int i = 0; i < len; i++) {
if (cursor.getObject().equals(drawing.getCTDrawing().getOneCellAnchorArray(i))) {
seleIn = i;
System.out.println("OneCellAnchor for picture " + xssfPicture + " was deleted.");
break;
}
}
if (seleIn != -1) {
drawing.getCTDrawing().removeOneCellAnchor(seleIn);
}
}
}
Now the way to update the image is as follows :
public static void updateXssfImg(Workbook wookbook,
Sheet sheet, String filePath, byte[] imgBytes,int row, int col, XSSFPicture xssfPicture) {
Log.e(TAG,"updateXssfImg, Row number :" + row + ", Number of columns :" + col+ ", Time :" + System.currentTimeMillis());
Drawing dg = sheet.createDrawingPatriarch();
deleteEmbeddedXSSFPicture(xssfPicture);
deleteCTAnchor(xssfPicture);
XSSFClientAnchor anchor = new XSSFClientAnchor(0,0,255,255, col, row,col+1,row+1);
anchor.setAnchorType(3);
// Insert a picture
dg.createPicture(anchor, wookbook.addPicture(imgBytes, XSSFWorkbook.PICTURE_TYPE_JPEG));
FileOutputStream fileOut = null;
try {
fileOut = new FileOutputStream(filePath);
// write in excel file
wookbook.write(fileOut);
Log.e(TAG, "----Excle File image Dele Updated ------"+ ", Time :" + System.currentTimeMillis());
} catch(IOException e) {
e.printStackTrace();
} finally {
if(fileOut != null) {
try {
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
It can really be updated .xlsx The picture in the picture , But the problem is , An exception will occur when the update is performed again , Cause crash . Tracking through code , Found to be wookbook.addPicture(imgBytes, XSSFWorkbook.PICTURE_TYPE_JPEG) There is an exception in this code ,A part with the name ‘XXXXXX’ already exists, Guess when the deletion might start , Some relevant contents have been deleted by mistake , Cause another execution error . Because I used to delete pictures before , Because the method was not found , So it's all right anchor Actions performed , No other operation , So I tried to delete only anchor Methods , Do not delete relations The operation of , Find it feasible . After repeated updates , The original picture was deleted . So the final solution is to deleteEmbeddedXSSFPicture(xssfPicture) Method delete , as follows :
public static void updateXssfImg(Workbook wookbook,
Sheet sheet, String filePath, byte[] imgBytes,int row, int col, XSSFPicture xssfPicture) {
Log.e(TAG,"updateXssfImg, Row number :" + row + ", Number of columns :" + col+ ", Time :" + System.currentTimeMillis());
Drawing dg = sheet.createDrawingPatriarch();
deleteCTAnchor(xssfPicture);
XSSFClientAnchor anchor = new XSSFClientAnchor(0,0,255,255, col, row,col+1,row+1);
anchor.setAnchorType(3);
// Insert a picture
dg.createPicture(anchor, wookbook.addPicture(imgBytes, XSSFWorkbook.PICTURE_TYPE_JPEG));
FileOutputStream fileOut = null;
try {
fileOut = new FileOutputStream(filePath);
// write in excel file
wookbook.write(fileOut);
Log.e(TAG, "----Excle File image Dele Updated ------"+ ", Time :" + System.currentTimeMillis());
} catch(IOException e) {
e.printStackTrace();
} finally {
if(fileOut != null) {
try {
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
All right , The final plan is like this .
边栏推荐
- (P14) use of the override keyword
- Dynamic segment tree leetcode six hundred and ninety-nine
- Audio and video engineer (Preliminary) (I) basic concepts of audio and video
- 【字符集六】宽字符串和多字节字符互转
- Close asymmetric key
- 通俗理解时域采样与频域延拓
- What is the MES system? What is the operation process of MES system?
- What is the quality traceability function of MES system pursuing?
- API handling Android security distance
- Background location case II
猜你喜欢

Priority issues

处理异常数据

43 cas d'analyse du réseau neuronal MATLAB: chapitre 7 régression du réseau RBF - - réalisation de la régression fonctionnelle non linéaire

JVM learning notes: garbage collection mechanism

Close asymmetric key

MSTP的配置与原理

ctfshow web4

Inheritance of row height

Display the remaining valid days according to the valid period

QT realizes multi screen and multi-resolution adaptation
随机推荐
Hypergeometric cumulative distribution test overlap
x64dbg 调试 EXCEPTION_ACCESS_VIOLATION C0000005
Centos8 installing MySQL 8.0 (upper)
[new planning]
43 cas d'analyse du réseau neuronal MATLAB: chapitre 7 régression du réseau RBF - - réalisation de la régression fonctionnelle non linéaire
ctfshow web4
API handling Android security distance
Oracle installation details (verification)
Install iptables services and open ports
Knee joint
Record the first step pit of date type
What should be paid attention to when establishing MES system? What benefits can it bring to the enterprise?
In the era of intelligent manufacturing, how do enterprises carry out digital transformation
Arrays in JS
第三章 寄存器 (内存访问)
Display the remaining valid days according to the valid period
Composition of box model
JVM learning notes: three local method interfaces and execution engines
2022.6.9-----leetcode. four hundred and ninety-seven
How to understand the production scheduling of APS system?