Java - получить XML (Excel) таблицу из буфера обмена - PullRequest
3 голосов
/ 04 августа 2020

Мне было интересно, можно ли получить необработанную таблицу XML из буфера обмена windows. Поскольку при просмотре буфера обмена с помощью средства просмотра буфера обмена (https://www.freeclipboardviewer.com/windowsclipboard/), XML Spreadsheet является одним из перечисленных вариантов. Однако, глядя на доступные Dataflavors через класс Java Clipboard, я могу найти только text/plain и text/html с разными кодировками и потоками / буферами / строками /...

Следовательно использование специального вкуса new DataFlavor("text/xml", "XML Spreadsheet"); не сработало, как я ожидал. Хотя использование HTML было бы вариантом, я бы предпочел иметь электронную таблицу, поскольку она содержит некоторую дополнительную информацию.

ОБНОВЛЕНИЕ

Я обнаружил что это возможно с помощью класса Java FX Clipboard, однако, с тех пор как Java 9? FX больше не входит в комплект, это было бы очень плохо, а также было бы отстойно инициализировать весь стек FX только для того, чтобы иметь возможность правильно получить доступ к буферу обмена.

1 Ответ

0 голосов
/ 19 августа 2020

Не существует способов AWT или Swing для получения данных Excel- XML (или двоичных ). Также см. Этот JDK Enhancement-Ticket с 2013 года.

Вы можете использовать JavaFX , SWT или «Windows -Only. "собственный Win32 API через JNA. Буфер обмена-документация от Microsoft мне очень помог:

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 «Цепочке просмотра буфера обмена» .

...