LIbreOffice UNO:如何创建文档中已存在的图像元素的复制/克隆并将其添加到新页面?

时间:2017-08-11 14:25:44

标签: java uno libreoffice-writer

我正在从文档模板以编程方式创建文档。该模板包含一个图像占位符,用于定义文档中图像的大小。然后将图像替换为渲染为相同大小的图形。但是,如果有太多数据要在一个图形中绘制所有数据,我想复制图像并将其添加到自己的新页面。我怎样才能做到这一点?我看到的唯一方法是创建一个新图像,然后只复制所有属性。然后将图像插入新页面。

1 个答案:

答案 0 :(得分:0)

我没有做到正确的复制粘贴,因为最后粘贴花了很长时间。所以我实现了我上面建议的内容并且效果很好。请注意,它在我的设置中有效,我不得不进行一些调整,找出哪些属性与复制相关,以重现相同的图像。因此,如果您知道自己正在使用某个属性,那么您也必须考虑这个属性。

这里最相关的部分是duplicateUnderlyingElement方法,它读取一个图像的重要属性并将它们写入新图像。

import com.sun.star.awt.Size;
import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.PropertyVetoException;
import com.sun.star.beans.UnknownPropertyException;
import com.sun.star.beans.XPropertySet;
import com.sun.star.graphic.XGraphic;
import com.sun.star.graphic.XGraphicProvider;
import com.sun.star.lang.IllegalArgumentException;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lib.uno.adapter.ByteArrayToXInputStreamAdapter;
import com.sun.star.text.TextContentAnchorType;
import com.sun.star.text.XText;
import com.sun.star.text.XTextCursor;
import com.sun.star.text.XTextDocument;
import com.sun.star.uno.Exception;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import org.jodconverter.office.LocalOfficeContext;
import org.jodconverter.office.LocalOfficeUtils;
import org.jodconverter.office.OfficeContext;

import java.io.IOException;

/**
 * The image binding allows the manipulation of an image object in libreoffice.
 * @author be
 */
public class ImageBinding extends ContentBinding {

    private XPropertySet propertySet = null;

    // properties to preserve
    private Integer width;
    private Integer height;
    private Integer horizontalPosition;
    private Integer verticalPosition;
    private TextContentAnchorType anchorType;
    private Short graphicRotation;
    private Short horiOrient;
    private Integer horiOrientPosition;
    private Short horiOrientRelation;
    private Short vertOrient;
    private Integer vertOrientPosition;
    private Short vertOrientRelation;
    private Short relativeWidth;
    private Short relativeHeight;
    private Short relativeWidthRelation;
    private Short relativeHeightRelation;


    public ImageBinding(XPropertySet propertySet) throws UnknownPropertyException, PropertyVetoException, WrappedTargetException, IOException {
        super();
        this.propertySet = propertySet;
        this.width = getImageWidth();
        this.height = getImageHeight();
        this.horizontalPosition = getHorizontalPosition();
        this.verticalPosition = getVerticalPosition();
        this.anchorType = getAnchorType();
        this.graphicRotation = getGraphicRotation();
        this.horiOrient = getHoriOrient();
        this.horiOrientPosition = getHoriOrientPosition();
        this.horiOrientRelation = getHoriOrientRelation();
        this.vertOrient = getVertOrient();
        this.vertOrientPosition = getVertOrientPosition();
        this.vertOrientRelation = getVertOrientRelation();
        this.relativeWidth = getRelativeWidth();
        this.relativeHeight = getRelativeHeight();
        this.relativeWidthRelation = getRelativeWidthRelation();
        this.relativeHeightRelation = getRelativeHeightRelation();
    }

    public void deleteUnderlyingElement(){
        if(propertySet != null){
            XComponent comp = UnoRuntime.queryInterface(XComponent.class, propertySet);
            comp.dispose();
        }
    }

    @Override
    public ImageBinding duplicateUnderlyingElement(XComponent document, XTextCursor documentBodyCursor) throws Exception, IOException {
        XTextDocument aTextDocument = UnoRuntime.queryInterface(com.sun.star.text.XTextDocument.class, document);
        XText documentBodyText = aTextDocument.getText();
        XMultiServiceFactory xDocMSF = UnoRuntime.queryInterface(com.sun.star.lang.XMultiServiceFactory.class, aTextDocument);

        Object oGraphic = xDocMSF.createInstance("com.sun.star.text.TextGraphicObject");                                            // Creating the service GraphicObject
        com.sun.star.text.XTextContent xTextContent = UnoRuntime.queryInterface(com.sun.star.text.XTextContent.class, oGraphic );   // Querying for the interface XTextContent on the GraphicObject
        documentBodyText.insertTextContent(documentBodyCursor, xTextContent, true);                                             // insert the image content

        XPropertySet xPropSet = UnoRuntime.queryInterface(com.sun.star.beans.XPropertySet.class, oGraphic);                         // query for the interface XPropertySet on GraphicObject

        // DIRTY SECTION: don´t ask, these properties were found through intelligent trial and error from the set of around 150 properties (= sweat and pain)
        // for now, we support copying of images whose size is defined as relative width and height (others scale strangely)
        // copy-pasting images leads to strange coupling of image properties, so that pasted images all change to the same properties (all the same image) if one is edited
        // If you know better, then do it better.
        xPropSet.setPropertyValue("AnchorType", anchorType );                                                                   // set the anchor type
        xPropSet.setPropertyValue("HoriOrientPosition", horizontalPosition);                                                    // set the horizontal position
        xPropSet.setPropertyValue("VertOrientPosition", verticalPosition );                                                     // set the vertical position

        xPropSet.setPropertyValue("Width", width);                                                                              // set the width
        xPropSet.setPropertyValue("Height", height);                                                                                // set the height

        xPropSet.setPropertyValue("GraphicRotation", graphicRotation);                                                          // set the graphic rotation
        xPropSet.setPropertyValue("HoriOrient", horiOrient);                                                                        // set the horizontal orientation
        xPropSet.setPropertyValue("HoriOrientPosition", horiOrientPosition);                                                        // set the horizontal orientation position
        xPropSet.setPropertyValue("HoriOrientRelation", horiOrientRelation);                                                        // set the horizontal orientation relation
        xPropSet.setPropertyValue("VertOrient", vertOrient);                                                                        // set the vertical orientation
        xPropSet.setPropertyValue("VertOrientPosition", vertOrientPosition);                                                        // set the vertical orientation position
        xPropSet.setPropertyValue("VertOrientRelation", vertOrientRelation);                                                        // set the vertical orientation relation
        xPropSet.setPropertyValue("RelativeWidth", relativeWidth);                                                              // set the relative width
        xPropSet.setPropertyValue("RelativeHeight", relativeHeight);                                                                // set the relative height
        xPropSet.setPropertyValue("RelativeWidthRelation", relativeWidthRelation);                                              // set the relative width relation
        xPropSet.setPropertyValue("RelativeHeightRelation", relativeHeightRelation);                                                // set the relative height relation

        ImageBinding b = new ImageBinding(xPropSet);
        return b;
    }

    /**
     * Inserts a graphic link to an image on the file system. This graphic is not embedded. For embedded graphics, see @setImageBytes().
     * @param url
     * @throws IllegalArgumentException
     * @throws UnknownPropertyException
     * @throws PropertyVetoException
     * @throws WrappedTargetException
     * @throws IOException
     */
    public void setImageFileURL(String url) throws IllegalArgumentException, UnknownPropertyException, PropertyVetoException, WrappedTargetException, IOException{
        // Creating a string for the graphic url
        java.io.File sourceFile = new java.io.File(url);
        StringBuffer sUrl = new StringBuffer("file:///");
        sUrl.append(sourceFile.getCanonicalPath().replace('\\', '/'));
        propertySet.setPropertyValue( "GraphicURL", sUrl.toString() );
    }

    public void setImageDataURL(String url) throws IllegalArgumentException, UnknownPropertyException, PropertyVetoException, WrappedTargetException{
        propertySet.setPropertyValue( "GraphicURL", url );
    }

    public void setImageBytes(OfficeContext context, byte[] imageAsByteArray) throws java.lang.Exception {
        if(context instanceof LocalOfficeContext){
            LocalOfficeContext lContext = (LocalOfficeContext) context;
            Object bitmapTableObject = lContext.getComponentContext().getServiceManager().createInstanceWithContext(
                    "com.sun.star.graphic.GraphicProvider", lContext.getComponentContext());

            XGraphicProvider xGraphicProvider = UnoRuntime.queryInterface(
                    XGraphicProvider.class, bitmapTableObject);

            PropertyValue[] v = new PropertyValue[1];
            v[0] = new PropertyValue();
            v[0].Name = "InputStream";
            v[0].Value = new ByteArrayToXInputStreamAdapter(imageAsByteArray);

            XGraphic graphic = xGraphicProvider.queryGraphic(v);
            if (graphic == null) {
                throw new java.lang.Exception("Image could not be found");
            }

            // Set the image
            propertySet.setPropertyValue("Graphic", graphic);
        }
    }

    public TextContentAnchorType getAnchorType() throws WrappedTargetException, UnknownPropertyException {
        return (TextContentAnchorType)propertySet.getPropertyValue("AnchorType");
    }

    public void setAnchorType(TextContentAnchorType type) throws WrappedTargetException, PropertyVetoException, UnknownPropertyException {
        propertySet.setPropertyValue("AnchorType", type);
    }

    public String getGraphicURL() throws WrappedTargetException, UnknownPropertyException {
        return (String) propertySet.getPropertyValue( "GraphicURL");
    }

    public void setGraphicURL(String graphicURL) throws WrappedTargetException, PropertyVetoException, UnknownPropertyException {
        propertySet.setPropertyValue( "GraphicURL", graphicURL );
    }

    public Integer getImageWidth() throws UnknownPropertyException, WrappedTargetException{
        return (Integer) propertySet.getPropertyValue("Width");
    }

    public void setImageWidth(Integer width) throws IllegalArgumentException, UnknownPropertyException, PropertyVetoException, WrappedTargetException{
        propertySet.setPropertyValue( "Width", Integer.valueOf(width));
    }

    public Integer getImageHeight() throws UnknownPropertyException, WrappedTargetException{
        return (Integer) propertySet.getPropertyValue("Height");
    }

    public void setImageHeight(Integer height) throws IllegalArgumentException, UnknownPropertyException, PropertyVetoException, WrappedTargetException{
        propertySet.setPropertyValue( "Height", Integer.valueOf(height));
    }

    public int getScaledImageWidth() throws UnknownPropertyException, WrappedTargetException{
        return (int) ((Integer) propertySet.getPropertyValue("Width")/15.0);
    }

    public void setScaledImageWidth(Integer width) throws IllegalArgumentException, UnknownPropertyException, PropertyVetoException, WrappedTargetException{
        propertySet.setPropertyValue( "Width", Integer.valueOf( width * 15 ) );
    }

    public int getScaledImageHeight() throws UnknownPropertyException, WrappedTargetException{
        return (int) ((Integer) propertySet.getPropertyValue("Height")/15.0);
    }

    public void setScaledImageHeight(Integer height) throws IllegalArgumentException, UnknownPropertyException, PropertyVetoException, WrappedTargetException{
        propertySet.setPropertyValue( "Height", Integer.valueOf( height * 15 ) );
    }

    public Integer getHorizontalPosition() throws IllegalArgumentException, UnknownPropertyException, PropertyVetoException, WrappedTargetException{
        return (Integer) propertySet.getPropertyValue( "HoriOrientPosition");
    }

    public void setHorizontalPosition(Integer pixelPosition) throws IllegalArgumentException, UnknownPropertyException, PropertyVetoException, WrappedTargetException{
        propertySet.setPropertyValue( "HoriOrientPosition", Integer.valueOf(pixelPosition));
    }

    public Integer getVerticalPosition() throws IllegalArgumentException, UnknownPropertyException, PropertyVetoException, WrappedTargetException{
        return (Integer)propertySet.getPropertyValue( "VertOrientPosition");
    }

    public void setVerticalPosition(Integer pixelPosition) throws IllegalArgumentException, UnknownPropertyException, PropertyVetoException, WrappedTargetException{
        propertySet.setPropertyValue( "VertOrientPosition", Integer.valueOf( pixelPosition ) );
    }

    private Size getActualSize() throws WrappedTargetException, UnknownPropertyException {
        return (Size) propertySet.getPropertyValue("ActualSize");
    }

    private Size getLayoutSize() throws WrappedTargetException, UnknownPropertyException {
        return (Size) propertySet.getPropertyValue("LayoutSize");
    }

    private Short getVertOrientRelation() throws WrappedTargetException, UnknownPropertyException {
        return (Short) propertySet.getPropertyValue("VertOrientRelation");
    }

    private Integer getVertOrientPosition() throws WrappedTargetException, UnknownPropertyException {
        return (Integer) propertySet.getPropertyValue("VertOrientPosition");
    }

    private Short getVertOrient() throws WrappedTargetException, UnknownPropertyException {
        return (Short) propertySet.getPropertyValue("VertOrient");
    }

    private Short getHoriOrientRelation() throws WrappedTargetException, UnknownPropertyException {
        return (Short) propertySet.getPropertyValue("HoriOrientRelation");
    }

    private Integer getHoriOrientPosition() throws WrappedTargetException, UnknownPropertyException {
        return (Integer) propertySet.getPropertyValue("HoriOrientPosition");
    }

    private Short getHoriOrient() throws WrappedTargetException, UnknownPropertyException {
        return (Short) propertySet.getPropertyValue("HoriOrient");
    }

    private Short getGraphicRotation() throws WrappedTargetException, UnknownPropertyException {
        return (Short) propertySet.getPropertyValue("GraphicRotation");
    }

    private Short getRelativeWidth() throws WrappedTargetException, UnknownPropertyException {
        return (Short) propertySet.getPropertyValue("RelativeWidth");
    }

    private Short getRelativeHeight() throws WrappedTargetException, UnknownPropertyException {
        return  (Short) propertySet.getPropertyValue("RelativeHeight");
    }

    private Short getRelativeHeightRelation() throws WrappedTargetException, UnknownPropertyException {
        return  (Short) propertySet.getPropertyValue("RelativeWidthRelation");
    }

    private Short getRelativeWidthRelation() throws WrappedTargetException, UnknownPropertyException {
        return  (Short) propertySet.getPropertyValue("RelativeHeightRelation");
    }

    public XPropertySet getPropertySet() {
        return propertySet;
    }
}