从Excel复制后剪贴板中的奇怪内容

时间:2017-03-20 14:22:55

标签: java excel swt clipboard

我正在尝试在我的应用程序中获取剪贴板的内容以确保excel兼容性,使用:

Clipboard clipboard = new Clipboard(Display.getDefault());
String contents = (String) clipboard.getContents(TextTransfer.getInstance());

问题是,如果我在一列[1,2,3]上,我选择单元格[1]和[3],那么在剪贴板内容中我找到了

  

1 \ r \ N 2 \ r \ N3 \ r \ n

而不仅仅是1和3.换句话说,剪贴板似乎不处理脱节的单元格。

有人知道发生了什么事吗?

1 个答案:

答案 0 :(得分:5)

我不相信这可能在Excel之外出于几个原因:

  1. 正如@Baz指出的那样,文本编辑器也会通过打印所有三个单元格的内容来做出响应。甚至Word都是这样做的。

    例如,假设我在Excel中打开了一个电子表格,其中包含以下内容:

    enter image description here

    然后在Word中插入一个新的Excel电子表格:

    enter image description here

    当我们尝试仅复制并粘贴包含AC的单元格时,我们会得到预期结果:

    enter image description here

    但是,如果在将新电子表格添加到Word文档时Excel未打开,我们会得到:

    enter image description here

    对我来说,这似乎表明,当Excel中的电子表格添加时Excel仍处于打开状态时,Excel的实例会以某种方式共享,这是它知道要粘贴哪些单元格的唯一方式。 (我正在使用Office 365

  2. 据我所知,Excel不会在剪贴板中放置任何内容来指示选择了哪些单元格。考虑到在Excel关闭后粘贴到Word中的结果,这是有意义的,但是为了进一步说明这是当只复制包含AC的单元格时Excel放入剪贴板的XML :

  3. <?xml version="1.0"?>
    <?mso-application progid="Excel.Sheet"?>
    <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40">
        <Styles>
            <Style ss:ID="Default" ss:Name="Normal">
                <Alignment ss:Vertical="Bottom"/>
                <Borders/>
                <Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11" ss:Color="#000000"/>
                <Interior/>
                <NumberFormat/>
                <Protection/>
            </Style>
        </Styles>
        <Worksheet ss:Name="Sheet1">
            <Table ss:ExpandedColumnCount="1" ss:ExpandedRowCount="3"
            ss:DefaultRowHeight="15">
                <Row>
                    <Cell><Data ss:Type="String">A</Data></Cell>
                </Row>
                <Row>
                    <Cell><Data ss:Type="String">B</Data></Cell>
                </Row>
                <Row>
                    <Cell><Data ss:Type="String">C</Data></Cell>
                </Row>
            </Table>
        </Worksheet>
    </Workbook>
    

    请注意,所有三个单元格的数据都存在于剪贴板内容中,并且没有任何内容可以指示选择了哪些单元格。

    为了获得这个XML,我扩展了&#34; XML Spreadsheet&#34;的ByteArrayTransfer类。键入只写入文件:

    public class ExcelTransfer extends ByteArrayTransfer {
    
        private static final String TYPE_NAME = "XML Spreadsheet";
        private static final int TYPE_ID = registerType(TYPE_NAME);
    
        private static final ExcelTransfer _instance = new ExcelTransfer();
    
        private ExcelTransfer() {
        }
    
        /**
         * @return
         */
        public static ExcelTransfer getInstance() {
            return _instance;
        }
    
        /**
         * {@inheritDoc}
         */
        @Override
        protected int[] getTypeIds() {
            return new int[] { TYPE_ID };
        }
    
        /**
         * {@inheritDoc}
         */
        @Override
        protected String[] getTypeNames() {
            return new String[] { TYPE_NAME };
        }
    
        /**
         * {@inheritDoc}
         */
        @Override
        protected void javaToNative(final Object object, final TransferData transferData) {
            // ...
        }
    
        /**
         * {@inheritDoc}
         */
        @Override
        protected Object nativeToJava(final TransferData transferData) {
            if (!isSupportedType(transferData)) {
                return null;
            }
    
            final byte[] buffer = (byte[]) super.nativeToJava(transferData);
            if (buffer == null) {
                return null;
            }
    
            final File f = new File("excel_clipboard.xml");
            try {
                f.createNewFile();
                final FileOutputStream fo = new FileOutputStream(f);
                fo.write(buffer);
                fo.close();
            } catch (final IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    在已复制的单元格中,运行:

    public static void main(final String... args) {
        new Clipboard(Display.getDefault()).getContents(ExcelTransfer.getInstance());
    }