Java - 从剪贴板中提取XML(Excel)电子表格

4
我想知道是否有可能从Windows剪贴板获取原始的XML电子表格。因为当使用剪贴板查看器(https://www.freeclipboardviewer.com/windowsclipboard/)查看剪贴板时,XML电子表格是列出的其中一种类型。但是,当通过Java Clipboard类查看可用的Dataflavors时,我只能找到具有不同编码和流/缓冲区/字符串/...的text/plaintext/html

因此,使用自定义类型new DataFlavor("text/xml", "XML Spreadsheet");并没有像我预期的那样工作。虽然使用HTML是一种选择,但我更喜欢电子表格,因为它包含了一些额外的信息。

更新

我发现这似乎可以通过Java FX Clipboard类实现,但是,由于Java 9以后?FX不再捆绑,这将是相当糟糕的事情,而且为了能够正确访问剪贴板而初始化整个FX堆栈也有点糟糕。

1个回答

2
没有AWT或Swing的方式来获取Excel-XML(或二进制)数据。还可以查看2013年的JDK Enhancement-Ticket
您可以使用JavaFXSWT或“仅限Windows”的本机Win32 API通过JNA。来自Microsoft的Clipboard-Documentation文档对我很有帮助。
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;

import com.sun.jna.Native;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinDef.BOOL;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.UINT;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.win32.StdCallLibrary;

/**
 * Shows the Excel-XML-clipboard content on Windows. Be sure to select some
 * cells in Excel and copy them with "Ctrl+C".
 * 
 * @author bobndrew
 */
public class WindowsSystemClipboardAccess {

    public interface User32 extends StdCallLibrary {
        User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);
        int CountClipboardFormats();
        UINT RegisterClipboardFormatA(String lpszFormat);
        BOOL OpenClipboard(HWND hWndNewOwner);
        BOOL CloseClipboard();
        HANDLE GetClipboardData(UINT uFormat);
        DWORD GetLastError();
    }

    public static void main(String args[]) throws Exception {
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        System.out.println("There are " + clipboard.getAvailableDataFlavors().length
                + " data flavors, but all are leading to a plainText- or htmlText-representation of the clipboard content:");
        for (DataFlavor flavor : clipboard.getAvailableDataFlavors()) {
            System.out.println(flavor.getHumanPresentableName() + "\t" + flavor);
        }

        System.out.println("\n\nSo we are using JNA to call the windows-API. The number of Windows-ClipboardFormats is "
            + User32.INSTANCE.CountClipboardFormats() + ".");

        UINT formatNumber = User32.INSTANCE.RegisterClipboardFormatA("XML Spreadsheet");
        System.out.println(formatNumber);
        System.out.println(User32.INSTANCE.OpenClipboard(null));
        HANDLE xmlData = User32.INSTANCE.GetClipboardData(formatNumber);
        System.out.println(xmlData);
        System.out.println(Kernel32.INSTANCE.GetLastError());
        System.out.println(Native.getLastError());
        System.out.println(User32.INSTANCE.CloseClipboard());

        System.out.println("\n" + xmlData.getPointer().getString(0));
    }
}

这个SSCCE示例的最后一行生成如下的xml:
<?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="Tabelle1">
  <Table ss:ExpandedColumnCount="4" ss:ExpandedRowCount="4"
   ss:DefaultColumnWidth="62.400000000000006" ss:DefaultRowHeight="14.4">
   <Row>
    <Cell ss:Index="2"><Data ss:Type="Number">1.2</Data></Cell>
    <Cell><Data ss:Type="Number">123</Data></Cell>
   </Row>
   <Row>
    <Cell ss:Index="2"><Data ss:Type="String">A String with 1 Number</Data></Cell>
    <Cell ss:Formula="=R[-1]C+R[-1]C[-1]"><Data ss:Type="Number">124.2</Data></Cell>
   </Row>
  </Table>
 </Worksheet>
</Workbook>

如果您想要疯狂,还可以进行一些“更改消息”的操作,在Windows“剪贴板查看器链”中(Clipboard Viewer Chain)注册您的应用程序窗口(registering your application-window)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接