从 Excel 复制后剪贴板中的奇怪内容
Weird content in the clipboard after copy from Excel
我正在尝试在我的应用程序中获取剪贴板的内容以确保 excel 兼容性,使用:
Clipboard clipboard = new Clipboard(Display.getDefault());
String contents = (String) clipboard.getContents(TextTransfer.getInstance());
问题是,如果我在一列 [1, 2, 3] 上有 select 个单元格 [1] 和 [3],那么在剪贴板内容中我发现
1\r\n2\r\n3\r\n
而不仅仅是 1 和 3。换句话说,剪贴板似乎无法处理不连续的单元格。
有人知道发生了什么事吗?
我认为这在 Excel 之外是不可能的,原因如下:
正如@Baz 所指出的,文本编辑器也通过打印所有三个单元格的内容来响应。甚至 Word 也这样做。
例如,假设我在 Excel 中打开了一个包含以下内容的电子表格:
然后在 Word 中插入一个新的 Excel 电子表格:
当我们尝试仅复制和粘贴包含 A
和 C
的单元格时,我们得到了预期的结果:
但是,如果在将新电子表格添加到 Word 文档时 Excel 未打开,我们将得到:
对我来说,这似乎表明当在 Word 中添加电子表格时 Excel 仍然打开时,Excel 的实例以某种方式共享,这是它知道哪些单元格要打开的唯一方法粘贴。 (我正在使用 Office 365)
据我所知,Excel 不会将任何内容放入剪贴板以指示选择了哪些单元格。考虑到在 Excel 关闭后粘贴到 Word 中的结果,这是有道理的,但为了进一步说明这一点,这是 Excel 在只有包含 [ 的单元格时放入剪贴板的 XML =13=] 和 C
被复制:
<?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,我将 ByteArrayTransfer
class 的 "XML Spreadsheet" 类型扩展为只写入一个文件:
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());
}
我正在尝试在我的应用程序中获取剪贴板的内容以确保 excel 兼容性,使用:
Clipboard clipboard = new Clipboard(Display.getDefault());
String contents = (String) clipboard.getContents(TextTransfer.getInstance());
问题是,如果我在一列 [1, 2, 3] 上有 select 个单元格 [1] 和 [3],那么在剪贴板内容中我发现
1\r\n2\r\n3\r\n
而不仅仅是 1 和 3。换句话说,剪贴板似乎无法处理不连续的单元格。
有人知道发生了什么事吗?
我认为这在 Excel 之外是不可能的,原因如下:
正如@Baz 所指出的,文本编辑器也通过打印所有三个单元格的内容来响应。甚至 Word 也这样做。
例如,假设我在 Excel 中打开了一个包含以下内容的电子表格:
然后在 Word 中插入一个新的 Excel 电子表格:
当我们尝试仅复制和粘贴包含
A
和C
的单元格时,我们得到了预期的结果:但是,如果在将新电子表格添加到 Word 文档时 Excel 未打开,我们将得到:
对我来说,这似乎表明当在 Word 中添加电子表格时 Excel 仍然打开时,Excel 的实例以某种方式共享,这是它知道哪些单元格要打开的唯一方法粘贴。 (我正在使用 Office 365)
据我所知,Excel 不会将任何内容放入剪贴板以指示选择了哪些单元格。考虑到在 Excel 关闭后粘贴到 Word 中的结果,这是有道理的,但为了进一步说明这一点,这是 Excel 在只有包含 [ 的单元格时放入剪贴板的 XML =13=] 和
C
被复制:
<?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,我将 ByteArrayTransfer
class 的 "XML Spreadsheet" 类型扩展为只写入一个文件:
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());
}