123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- /* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ==================================================================== */
-
- package org.apache.poi.xssf.usermodel;
-
- import java.io.IOException;
- import java.io.OutputStream;
- import java.util.HashMap;
- import java.util.Map;
-
- import javax.xml.namespace.QName;
-
- import org.apache.poi.POIXMLDocumentPart;
- import org.apache.poi.xssf.model.CommentsTable;
- import org.apache.poi.openxml4j.opc.PackagePart;
- import org.apache.poi.openxml4j.opc.PackagePartName;
- import org.apache.poi.openxml4j.opc.PackageRelationship;
- import org.apache.poi.openxml4j.opc.TargetMode;
- import org.apache.poi.ss.usermodel.ClientAnchor;
- import org.apache.poi.ss.usermodel.Drawing;
- import org.apache.xmlbeans.XmlException;
- import org.apache.xmlbeans.XmlOptions;
- import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTConnector;
- import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTDrawing;
- import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGroupShape;
- import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTPicture;
- import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape;
- import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor;
- import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.STEditAs;
- import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
-
- /**
- * Represents a SpreadsheetML drawing
- *
- * @author Yegor Kozlov
- */
- public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing {
- /**
- * Root element of the SpreadsheetML Drawing part
- */
- private CTDrawing drawing;
- private boolean isNew;
-
- /**
- * Create a new SpreadsheetML drawing
- *
- * @see org.apache.poi.xssf.usermodel.XSSFSheet#createDrawingPatriarch()
- */
- protected XSSFDrawing() {
- super();
- drawing = newDrawing();
- isNew = true;
- }
-
- /**
- * Construct a SpreadsheetML drawing from a package part
- *
- * @param part the package part holding the drawing data,
- * the content type must be <code>application/vnd.openxmlformats-officedocument.drawing+xml</code>
- * @param rel the package relationship holding this drawing,
- * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing
- */
- protected XSSFDrawing(PackagePart part, PackageRelationship rel) throws IOException, XmlException {
- super(part, rel);
- drawing = CTDrawing.Factory.parse(part.getInputStream());
- }
-
- /**
- * Construct a new CTDrawing bean. By default, it's just an empty placeholder for drawing objects
- *
- * @return a new CTDrawing bean
- */
- private static CTDrawing newDrawing(){
- return CTDrawing.Factory.newInstance();
- }
-
- /**
- * Return the underlying CTDrawing bean, the root element of the SpreadsheetML Drawing part.
- *
- * @return the underlying CTDrawing bean
- */
- public CTDrawing getCTDrawing(){
- return drawing;
- }
-
- @Override
- protected void commit() throws IOException {
- XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
-
- /*
- Saved drawings must have the following namespaces set:
- <xdr:wsDr
- xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
- xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">
- */
- if(isNew) xmlOptions.setSaveSyntheticDocumentElement(new QName(CTDrawing.type.getName().getNamespaceURI(), "wsDr", "xdr"));
- Map<String, String> map = new HashMap<String, String>();
- map.put("http://schemas.openxmlformats.org/drawingml/2006/main", "a");
- map.put(STRelationshipId.type.getName().getNamespaceURI(), "r");
- xmlOptions.setSaveSuggestedPrefixes(map);
-
- PackagePart part = getPackagePart();
- OutputStream out = part.getOutputStream();
- drawing.save(out, xmlOptions);
- out.close();
- }
-
- /**
- * Constructs a textbox under the drawing.
- *
- * @param anchor the client anchor describes how this group is attached
- * to the sheet.
- * @return the newly created textbox.
- */
- public XSSFTextBox createTextbox(XSSFClientAnchor anchor){
- CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
- CTShape ctShape = ctAnchor.addNewSp();
- ctShape.set(XSSFSimpleShape.prototype());
- XSSFTextBox shape = new XSSFTextBox(this, ctShape);
- shape.anchor = anchor;
- return shape;
-
- }
-
- /**
- * Creates a picture.
- *
- * @param anchor the client anchor describes how this picture is attached to the sheet.
- * @param pictureIndex the index of the picture in the workbook collection of pictures,
- * {@link org.apache.poi.xssf.usermodel.XSSFWorkbook#getAllPictures()} .
- *
- * @return the newly created picture shape.
- */
- public XSSFPicture createPicture(XSSFClientAnchor anchor, int pictureIndex)
- {
- PackageRelationship rel = addPictureReference(pictureIndex);
-
- CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
- CTPicture ctShape = ctAnchor.addNewPic();
- ctShape.set(XSSFPicture.prototype());
-
- XSSFPicture shape = new XSSFPicture(this, ctShape);
- shape.anchor = anchor;
- shape.setPictureReference(rel);
- return shape;
- }
-
- public XSSFPicture createPicture(ClientAnchor anchor, int pictureIndex){
- return createPicture((XSSFClientAnchor)anchor, pictureIndex);
- }
-
- /**
- * Add the indexed picture to this drawing relations
- *
- * @param pictureIndex the index of the picture in the workbook collection of pictures,
- * {@link org.apache.poi.xssf.usermodel.XSSFWorkbook#getAllPictures()} .
- */
- protected PackageRelationship addPictureReference(int pictureIndex){
- XSSFWorkbook wb = (XSSFWorkbook)getParent().getParent();
- XSSFPictureData data = wb.getAllPictures().get(pictureIndex);
- PackagePartName ppName = data.getPackagePart().getPartName();
- PackageRelationship rel = getPackagePart().addRelationship(ppName, TargetMode.INTERNAL, XSSFRelation.IMAGES.getRelation());
- addRelation(new XSSFPictureData(data.getPackagePart(), rel));
- return rel;
- }
-
- /**
- * Creates a simple shape. This includes such shapes as lines, rectangles,
- * and ovals.
- *
- * @param anchor the client anchor describes how this group is attached
- * to the sheet.
- * @return the newly created shape.
- */
- public XSSFSimpleShape createSimpleShape(XSSFClientAnchor anchor)
- {
- CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
- CTShape ctShape = ctAnchor.addNewSp();
- ctShape.set(XSSFSimpleShape.prototype());
- XSSFSimpleShape shape = new XSSFSimpleShape(this, ctShape);
- shape.anchor = anchor;
- return shape;
- }
-
- /**
- * Creates a simple shape. This includes such shapes as lines, rectangles,
- * and ovals.
- *
- * @param anchor the client anchor describes how this group is attached
- * to the sheet.
- * @return the newly created shape.
- */
- public XSSFConnector createConnector(XSSFClientAnchor anchor)
- {
- CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
- CTConnector ctShape = ctAnchor.addNewCxnSp();
- ctShape.set(XSSFConnector.prototype());
-
- XSSFConnector shape = new XSSFConnector(this, ctShape);
- shape.anchor = anchor;
- return shape;
- }
-
- /**
- * Creates a simple shape. This includes such shapes as lines, rectangles,
- * and ovals.
- *
- * @param anchor the client anchor describes how this group is attached
- * to the sheet.
- * @return the newly created shape.
- */
- public XSSFShapeGroup createGroup(XSSFClientAnchor anchor)
- {
- CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
- CTGroupShape ctGroup = ctAnchor.addNewGrpSp();
- ctGroup.set(XSSFShapeGroup.prototype());
-
- XSSFShapeGroup shape = new XSSFShapeGroup(this, ctGroup);
- shape.anchor = anchor;
- return shape;
- }
-
- /**
- * Creates a cell comment.
- *
- * @param anchor the client anchor describes how this comment is attached
- * to the sheet.
- * @return the newly created comment.
- */
- @Override
- public XSSFComment createCellComment(ClientAnchor anchor)
- {
- XSSFClientAnchor ca = (XSSFClientAnchor)anchor;
- XSSFSheet sheet = (XSSFSheet)getParent();
-
- //create comments and vmlDrawing parts if they don't exist
- CommentsTable comments = sheet.getCommentsTable(true);
- XSSFVMLDrawing vml = sheet.getVMLDrawing(true);
- schemasMicrosoftComVml.CTShape vmlShape = vml.newCommentShape();
- if(ca.isSet()){
- String position =
- ca.getCol1() + ", 0, " + ca.getRow1() + ", 0, " +
- ca.getCol2() + ", 0, " + ca.getRow2() + ", 0";
- vmlShape.getClientDataArray(0).setAnchorArray(0, position);
- }
- XSSFComment shape = new XSSFComment(comments, comments.newComment(), vmlShape);
- shape.setColumn(ca.getCol1());
- shape.setRow(ca.getRow1());
- return shape;
- }
-
- /**
- * Create and initialize a CTTwoCellAnchor that anchors a shape against top-left and bottom-right cells.
- *
- * @return a new CTTwoCellAnchor
- */
- private CTTwoCellAnchor createTwoCellAnchor(XSSFClientAnchor anchor) {
- CTTwoCellAnchor ctAnchor = drawing.addNewTwoCellAnchor();
- ctAnchor.setFrom(anchor.getFrom());
- ctAnchor.setTo(anchor.getTo());
- ctAnchor.addNewClientData();
- anchor.setTo(ctAnchor.getTo());
- anchor.setFrom(ctAnchor.getFrom());
- STEditAs.Enum aditAs;
- switch(anchor.getAnchorType()) {
- case ClientAnchor.DONT_MOVE_AND_RESIZE: aditAs = STEditAs.ABSOLUTE; break;
- case ClientAnchor.MOVE_AND_RESIZE: aditAs = STEditAs.TWO_CELL; break;
- case ClientAnchor.MOVE_DONT_RESIZE: aditAs = STEditAs.ONE_CELL; break;
- default: aditAs = STEditAs.ONE_CELL;
- }
- ctAnchor.setEditAs(aditAs);
- return ctAnchor;
- }
- }
|