0

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

4

1 回答 1

0

I did not achieve to do proper copy-pasting, since it took pretty long for pasting in the end. So I implemented what I suggested above and it works pretty well. Be warned that it worked in my setting and I had to fight a bit finding out which properties are relevant to be copied over to reproduce about the same image. So if you know you are using a certain property, then you must consider that one too here.

The most relevant part here is the duplicateUnderlyingElement method, which reads the important properties of one image and writes them into a new image.

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;
    }
}
于 2018-05-09T09:27:26.353 回答