当今很多业务应用程序都是使用 Java 开发的,并且以后这种用 Java 开发的应用会更多。而在许多应用程序都使用了 Swing 的 JTable 组件,以类似电子表格的格式显示数据。如果业务应用程序可以将数据导入 Microsoft Excel 和从 Microsoft Excel 中导出数据,则会为用户带来方便,使用户可以使用无处不在的该电子表格程序的强大功能。此 Java 技巧将帮助您理解系统剪贴板,并使您的 JTable 能够与 Excel 交互和互操作。您将看到,通过在当前应用程序中仅仅添加另外的一行代码即可实现这一有用功能的添加。
要实现这一目标,需要做的只是复制这里给出的文件 ExcelAdapter.java,对其进行编译,并确保您的应用程序可以找到 ExcelAdapter.class 文件;做完后,JTable 就可以与 Excel 进行通话了!我们将向您展示仅通过这一行代码,如何实现到 Excel 的复制 (Ctrl+C) 和粘贴 (Ctrl+V) 以及从 Excel 进行的复制和粘贴。另外还提供了一个使用 ExcelAdapter 的示例应用程序。
代码
下面是实际完成此任务的适配器代码(称为 ExcelAdapter.java):
import java.awt.*;import java.awt.event.*;import javax.swing.*;import java.awt.datatransfer.*;import java.util.*;/** * ExcelAdapter 实现 JTables 中的复制粘贴 * 剪贴板功能。 适配器所用的剪贴板数据格式 * 与 Excel 所用的剪贴板格式兼容。这提供了 * 支持的 JTables 和 Excel 间的互操作。 */public class ExcelAdapter implements ActionListener { private String rowstring,value; private Clipboard system; private StringSelection stsel; private JTable jTable1 ; /** * Excel 适配器由 JTable 构成, * 它实现了 JTable 上的复制粘贴 * 功能,并充当剪贴板监听程序。 */public ExcelAdapter(JTable myJTable) { jTable1 = myJTable; KeyStroke copy = KeyStroke.getKeyStroke(KeyEvent.VK_C,ActionEvent.CTRL_MASK,false); // 确定复制按键用户可以对其进行修改 // 以实现其它按键组合的复制功能。 KeyStroke paste = KeyStroke.getKeyStroke(KeyEvent.VK_V,ActionEvent.CTRL_MASK,false); // 确定粘贴按键用户可以对其进行修改 // 以实现其它按键组合的复制功能。jTable1.registerKeyboardAction(this,"Copy",copy,JComponent.WHEN_FOCUSED);jTable1.registerKeyboardAction(this,"Paste",paste,JComponent.WHEN_FOCUSED); system = Toolkit.getDefaultToolkit().getSystemClipboard(); } /** * 此适配器运行图表的公共读方法。 */public JTable getJTable() {return jTable1;}public void setJTable(JTable jTable1) {this.jTable1=jTable1;} /** * 在我们监听此实现的按键上激活这种方法。 * 此处,它监听复制和粘贴 ActionCommands。 * 包含不相邻单元格的选择导致选择无效, * 而且此后复制动作无法执行。 * 粘贴的方法是将选定内容的左上角与 * JTable 的当前选定内容的第一个元素对齐。 */public void actionPerformed(ActionEvent e) { if (e.getActionCommand().compareTo("Copy")==0) { StringBuffer sbf=new StringBuffer(); // 检查以确保我们仅选择了单元格的 // 相邻块 int numcols=jTable1.getSelectedColumnCount(); int numrows=jTable1.getSelectedRowCount(); int[] rowsselected=jTable1.getSelectedRows(); int[] colsselected=jTable1.getSelectedColumns(); if (!((numrows-1==rowsselected[rowsselected.length-1]-rowsselected[0] && numrows==rowsselected.length) &&(numcols-1==colsselected[colsselected.length-1]-colsselected[0] && numcols==colsselected.length))) { JOptionPane.showMessageDialog(null, "Invalid Copy Selection", "Invalid Copy Selection", JOptionPane.ERROR_MESSAGE); return; } for (int i=0;i<numrows;i++) { for (int j=0;j<numcols;j++) {sbf.append(jTable1.getValueAt(rowsselected[i],colsselected[j])); if (j<numcols-1) sbf.append(" "); } sbf.append("
"); } stsel = new StringSelection(sbf.toString()); system = Toolkit.getDefaultToolkit().getSystemClipboard(); system.setContents(stsel,stsel); } if (e.getActionCommand().compareTo("Paste")==0) { System.out.println("Trying to Paste"); int startRow=(jTable1.getSelectedRows())[0]; int startCol=(jTable1.getSelectedColumns())[0]; try { String trstring= (String)(system.getContents(this).getTransferData(DataFlavor.stringFlavor)); System.out.println("String is:"+trstring); StringTokenizer st1=new StringTokenizer(trstring,"
"); for(int i=0;st1.hasMoreTokens();i++) { rowstring=st1.nextToken(); StringTokenizer st2=new StringTokenizer(rowstring," "); for(int j=0;st2.hasMoreTokens();j++) { value=(String)st2.nextToken(); if (startRow+i< jTable1.getRowCount() && startCol+j< jTable1.getColumnCount()) jTable1.setValueAt(value,startRow+i,startCol+j); System.out.println("Putting "+ value+"atrow="+startRow+i+"column="+startCol+j); } } } catch(Exception ex){ex.printStackTrace();} } }}
示例应用程序
下面是示例应用程序 Frame1.java,它使用 ExcelAdapter 实现 JTable 与 Excel 的兼容。
import java.awt.*;import javax.swing.*;public class Frame1 extends Frame { BorderLayout borderLayout1 = new BorderLayout(); JTable jTable1 ; Object[][] data=new Object[4][4]; Object header[]= {"Jan","Feb","Mar","Apr"};public static void main(String args[]) { Frame1 myframe=new Frame1(); myframe.setSize(new Dimension(250,250)); myframe.setVisible(true); }public Frame1() { super(); try { jbInit(); } catch (Exception e) { e.printStackTrace(); } }private void jbInit() throws Exception { for (int i=0;i<4;i++) for (int j=0;j<4;j++) data[i][j]=new Integer(i*10+j); System.out.println("Header length="+header[1]); jTable1=new JTable(data,header); jTable1.setCellSelectionEnabled(true); this.setTitle("Excel Lent JTABLE"); jTable1.setBackground(Color.pink); this.setLayout(borderLayout1); this.setSize(new Dimension(400, 300)); this.setBackground(Color.white); this.add(jTable1, BorderLayout.CENTER); // 这就是添加复制和粘贴功能的那一行! ExcelAdapter myAd = new ExcelAdapter(jTable1); }}