当前位置:网站首页>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 .
边栏推荐
- 记Date类型的一次踩坑
- 【字符集六】宽字符串和多字节字符互转
- R loop assignment variable name
- Error: ER_ NOT_ SUPPORTED_ AUTH_ MODE: Client does not support authentication protocol requested ... ...
- Regular verification user name
- Build personal blog and web.
- 【动态内存管理】malloc&calloc和realloc和笔试题和柔性数组
- What exactly is APS? You will know after reading the article
- The electrical fire detector monitors each power circuit in real time
- Only use MES as a tool? Looks like you missed the most important thing
猜你喜欢
![[advanced pointer I] character array & array pointer & pointer array](/img/ea/150b2162e4e1641eee7e852935d101.png)
[advanced pointer I] character array & array pointer & pointer array

Box model border

Priority issues

The Three Kingdoms kill the surrounding areas -------- explanation of the pig Kingdom kill problem

Hypergeometric cumulative distribution test overlap

【 pointeur avancé Ⅲ】 mise en œuvre de la fonction de tri rapide qsort& fonction de rappel en langage C

ctfshow web4
![[dynamic memory management] malloc & calloc and realloc and written test questions and flexible array](/img/d2/a6276d8415c46124920395df5651d1.png)
[dynamic memory management] malloc & calloc and realloc and written test questions and flexible array

【字符集九】gbk拷贝到Unicode会乱码?

Centso8 installing mysql8.0 (Part 2)
随机推荐
Install iptables services and open ports
Project sorting of niuke.com
(P13) use of final keyword
When converting tensor to ndarray in tensorflow, the run or Eval function is constantly called in the loop, and the code runs more and more slowly!
Composition of box model
Website colab and kaggle
Random acquisition of 4-digit non repeated verification code
Close asymmetric key
Audio and video engineer (Preliminary) (I) basic concepts of audio and video
The newline character with in the string is converted to an array
调整svg宽高
Shell basic syntax -- array
The electrical fire detector monitors each power circuit in real time
Loading circling effect during loading
Box model border
Error: clear the history in the search box in the website?
在Tensorflow中把Tensor转换为ndarray时,循环中不断调用run或者eval函数,代码运行越来越慢!
Engineers learn music theory (III) interval mode and chord
[advanced pointer 2] array parameter transfer & pointer parameter transfer & function pointer & function pointer array & callback function
Calling stored procedures in mysql, definition of variables,