すべてのワークシートのすべてのイメージを既存のExcelファイルから新しいExcelファイルにコピーしようとしています。このために、私は既存のExcelファイルからすべてのシートを読み、新しいExcelファイルに画像をコピーします。次のコードはすべてのシートにアクセスし、すべてのイメージを新しいシートにコピーしようとします。Apache POIを使用してすべてのExcelワークシートからイメージを読み取る
public static void modifyExcelFile(XSSFWorkbook xssfWorkbook) throws InvalidFormatException, IOException, XmlException{
String newFileName = "outputexcelfile.xlsx";
XSSFWorkbook dest = new XSSFWorkbook("test.xlsx");
int numSheets = xssfWorkbook.getNumberOfSheets();
// clone the template sheet additional number of times required
for(int i=1; i<numSheets; i++){
dest.cloneSheet(0);
}
for(int i=0; i<numSheets; i++) {
XSSFSheet destSheet = dest.getSheetAt(i);
dest.setSheetName(i, xssfWorkbook.getSheetName(i));
XSSFSheet sheet = xssfWorkbook.getSheetAt(i);
// copy images
System.out.println("Copying images ...");
copyImages(sheet, destSheet);
}
writeFile(dest, newFileName);
}
test.xlsxは1枚のテンプレートファイルです。次のcopyImages関数は、すべての画像を1つのシートから別のシートにコピーしようとします。
public static void copyImages(XSSFSheet from, XSSFSheet to) throws IOException, XmlException, InvalidFormatException{
Drawing drawingPatriarch = to.createDrawingPatriarch();
XSSFWorkbook destWorkbook = to.getWorkbook();
// Add image
for (POIXMLDocumentPart pdp : from.getRelations()) {
if (!XSSFRelation.DRAWINGS.getRelation().equals(pdp.getPackageRelationship().getRelationshipType())) continue;
PackagePart drawPP = pdp.getPackagePart();
WsDrDocument draw = WsDrDocument.Factory.parse(drawPP.getInputStream());
for (CTTwoCellAnchor twoAnc : draw.getWsDr().getTwoCellAnchorList()) {
String picId = twoAnc.getPic().getBlipFill().getBlip().getEmbed();
PackageRelationship pr = drawPP.getRelationship(picId);
PackagePart imgPP = drawPP.getRelatedPart(pr);
System.out.println(imgPP.getPartName() + ": contentType: " + imgPP.getContentType() + " size: " + imgPP.getSize()
+ ": picId: " + picId
+" - Col1: "+twoAnc.getFrom().getCol()
+" - Row1: "+twoAnc.getFrom().getRow()
+" - Col2: "+twoAnc.getTo().getCol()
+" - Row2: "+twoAnc.getTo().getRow()
);
// skip the logo
if(twoAnc.getFrom().getCol()==0 && twoAnc.getFrom().getRow()==0)
continue;
try {
InputStream is = imgPP.getInputStream();
byte[] bytes = IOUtils.toByteArray(is);
int pictureIdx = destWorkbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
is.close();
CreationHelper helper = destWorkbook.getCreationHelper();
//add a picture shape
ClientAnchor anchor = helper.createClientAnchor();
//set top-left corner of the picture,
anchor.setCol1(twoAnc.getFrom().getCol());
anchor.setRow1(twoAnc.getFrom().getRow());
anchor.setRow2(twoAnc.getTo().getRow());
anchor.setCol2(twoAnc.getTo().getCol());
Picture pict = drawingPatriarch.createPicture(anchor, pictureIdx);
}catch(IOException ioEx){
System.out.println("Failed to add icons. Details: " + ioEx.getMessage());
}
}
}
}
コードを実行すると、最初のシートの画像のみが正常にコピーされます。他のすべてのシートについては、画像はありません。コードはエラーなしで正常に実行されます。どんな助けでも大歓迎です。ありがとう!
[ClientAnchor](https://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/ClientAnchor.html)は、左上のアンカーセルから右下のアンカーセルまでではなく、上端のアンカーセル左アンカーセル+このセルの右下のアンカーセルへのx/yオフセット+このセルのx/yオフセット。オフセットは 'apache poi'の' Dx1'、 'Dy1'と' Dx2'、 'Dy2'という名前です。 –
@AxelRichter:resize()関数を呼び出さないと、常にDx1-2、Dy1-2について言及する必要はありますか? – Masum
はい、ピクチャが** one **セルに収まる場合、左上のアンカーセルと右下のアンカーセルは同じになるため、オフセットがなければ、ピクチャサイズはアンカーに依存します。その後、resize()だけがネイティブサイズに修正されます。 –