在剪贴板javaFx中保存表格



我开始在JavaFx中开发,我有一个项目,我想知道是否有可能在JavaFx中制作一个表的"复制粘贴"。我的意思是,我有一个带有一些数据的TableView我想把它保存在剪贴板中导出到Microsoft word或其他文本编辑器。这可能吗?我怎么能做到呢?由于

这是一个关于如何使用TableView复制/粘贴的例子。您必须根据您的属性类型扩展类。Excel保留表格结构,因为它支持在代码(n, t)中使用的Ascii空格。

一个改进的解决方案是使用混合剪贴板内容,以便将ClipboardContent也结构为html。然后在Word等程序中也会得到表结构。

TableCopyPasteCellsDemo.java

import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class TableCopyPasteCellsDemo extends Application {
    private final ObservableList<Person> data = FXCollections.observableArrayList(new Person("Jacob", "Smith", 18), new Person("Isabella", "Johnson", 19), new Person("Ethan", "Williams", 20), new Person("Michael", "Brown", 21));
    public static void main(String[] args) {
        launch(args);
    }
    @Override
    public void start(Stage stage) {
        stage.setWidth(500);
        stage.setHeight(550);
        // create table columns
        TableColumn<Person, String> firstNameCol = new TableColumn<Person, String>("First Name");
        firstNameCol.setMinWidth(100);
        firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));

        // firstNameCol.setVisible(false); // hide column for testing view/model indices

        TableColumn<Person, String> lastNameCol = new TableColumn<Person, String>("Last Name");
        lastNameCol.setMinWidth(100);
        lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName"));
        TableColumn<Person, Integer> ageCol = new TableColumn<Person, Integer>("Age");
        ageCol.setMinWidth(60);
        ageCol.setCellValueFactory(new PropertyValueFactory<Person, Integer>("age"));

        TableView<Person> table = new TableView<>();
        table.setPlaceholder(new Text("No content in table"));
        table.setItems(data);
        table.getColumns().addAll(firstNameCol, lastNameCol, ageCol);
        final VBox vbox = new VBox();
        vbox.setSpacing(5);
        vbox.setPadding(new Insets(10, 10, 10, 10));
        BorderPane borderPane = new BorderPane();
        borderPane.setCenter(table);
        vbox.getChildren().addAll(borderPane);
        vbox.getChildren().add( new Label( "Select cells and press CTRL+C. Paste the data into Excel or Notepad"));
        Scene scene = new Scene(vbox);
        stage.setScene(scene);
        stage.show();
        // enable multi-selection
        table.getSelectionModel().setCellSelectionEnabled(true);
        table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        // enable copy/paste
        TableUtils.installCopyPasteHandler(table);
    }

    public static class Person {
        private final StringProperty firstName;
        private final StringProperty lastName;
        private final IntegerProperty age;
        private Person(String fName, String lName, Integer age) {
            this.firstName = new SimpleStringProperty(fName);
            this.lastName = new SimpleStringProperty(lName);
            this.age = new SimpleIntegerProperty(age);
        }
        public final StringProperty firstNameProperty() {
            return this.firstName;
        }
        public final java.lang.String getFirstName() {
            return this.firstNameProperty().get();
        }
        public final void setFirstName(final java.lang.String firstName) {
            this.firstNameProperty().set(firstName);
        }
        public final StringProperty lastNameProperty() {
            return this.lastName;
        }
        public final java.lang.String getLastName() {
            return this.lastNameProperty().get();
        }
        public final void setLastName(final java.lang.String lastName) {
            this.lastNameProperty().set(lastName);
        }
        public final IntegerProperty ageProperty() {
            return this.age;
        }
        public final int getAge() {
            return this.ageProperty().get();
        }
        public final void setAge(final int age) {
            this.ageProperty().set(age);
        }
    }

}

TableUtils.java

import java.text.NumberFormat;
import java.text.ParseException;
import java.util.StringTokenizer;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.KeyEvent;
public class TableUtils {
    private static NumberFormat numberFormatter = NumberFormat.getNumberInstance();

    /**
     * Install the keyboard handler:
     *   + CTRL + C = copy to clipboard
     *   + CTRL + V = paste to clipboard
     * @param table
     */
    public static void installCopyPasteHandler(TableView<?> table) {
        // install copy/paste keyboard handler
        table.setOnKeyPressed(new TableKeyEventHandler());
    }
    /**
     * Copy/Paste keyboard event handler.
     * The handler uses the keyEvent's source for the clipboard data. The source must be of type TableView.
     */
    public static class TableKeyEventHandler implements EventHandler<KeyEvent> {
        KeyCodeCombination copyKeyCodeCompination = new KeyCodeCombination(KeyCode.C, KeyCombination.CONTROL_ANY);
        KeyCodeCombination pasteKeyCodeCompination = new KeyCodeCombination(KeyCode.V, KeyCombination.CONTROL_ANY);
        public void handle(final KeyEvent keyEvent) {
            if (copyKeyCodeCompination.match(keyEvent)) {
                if( keyEvent.getSource() instanceof TableView) {
                    // copy to clipboard
                    copySelectionToClipboard( (TableView<?>) keyEvent.getSource());
                    // event is handled, consume it
                    keyEvent.consume();
                }
            } 
            else if (pasteKeyCodeCompination.match(keyEvent)) {
                if( keyEvent.getSource() instanceof TableView) {
                    // copy to clipboard
                    pasteFromClipboard( (TableView<?>) keyEvent.getSource());
                    // event is handled, consume it
                    keyEvent.consume();
                }
            } 
        }
    }
    /**
     * Get table selection and copy it to the clipboard.
     * @param table
     */
    public static void copySelectionToClipboard(TableView<?> table) {
        StringBuilder plainBuffer = new StringBuilder();
        StringBuilder htmlBuffer = new StringBuilder();
        ObservableList<TablePosition> positionList = table.getSelectionModel().getSelectedCells();
        int prevRow = -1;
        htmlBuffer.append( "<html>n<body>n<table>n");
        htmlBuffer.append( " <tr>n");
        for (TablePosition position : positionList) {
            int viewRow = position.getRow();
            int viewCol = position.getColumn();
            // determine whether we advance in a row (tab) or a column
            // (newline).
            if (prevRow == viewRow) {
                plainBuffer.append('t');
            } else if (prevRow != -1) {
                plainBuffer.append('n');
                htmlBuffer.append( " </tr>n <tr>n");
            }
            // create string from cell
            String text = "";
            Object observableValue = (Object) table.getVisibleLeafColumn(viewCol).getCellObservableValue( viewRow); // table position gives the view index => we need to operate on the view columns
            // null-check: provide empty string for nulls
            if (observableValue == null) {
                text = "";
            }
            else if( observableValue instanceof DoubleProperty) { // TODO: handle boolean etc
                text = numberFormatter.format( ((DoubleProperty) observableValue).get());
            }
            else if( observableValue instanceof IntegerProperty) { 
                text = numberFormatter.format( ((IntegerProperty) observableValue).get());
            }                   
            else if( observableValue instanceof StringProperty) { 
                text = ((StringProperty) observableValue).get();
            }
            else {
                System.out.println("Unsupported observable value: " + observableValue);
            }
            // add new item to clipboard
            plainBuffer.append(text);
            htmlBuffer.append( "  <td>" + text + "</td>n");
            // remember previous
            prevRow = viewRow;
        }
        htmlBuffer.append( " </tr>n");
        htmlBuffer.append( "</table>n</body>n</html>");
        // create clipboard content
        final ClipboardContent clipboardContent = new ClipboardContent();
        clipboardContent.putString(plainBuffer.toString());
        clipboardContent.putHtml(htmlBuffer.toString());
        System.out.println("ascii:n" + plainBuffer.toString() + "nnhtml:n" + htmlBuffer.toString());
        // set clipboard content
        Clipboard.getSystemClipboard().setContent(clipboardContent);

    }
    public static void pasteFromClipboard( TableView<?> table) {
        // abort if there's not cell selected to start with
        if( table.getSelectionModel().getSelectedCells().size() == 0) {
            return;
        }
        // get the cell position to start with
        TablePosition pasteCellPosition = table.getSelectionModel().getSelectedCells().get(0);
        System.out.println("Pasting into cell " + pasteCellPosition);
        String pasteString = Clipboard.getSystemClipboard().getString();
        System.out.println(pasteString);
        int rowClipboard = -1;
        StringTokenizer rowTokenizer = new StringTokenizer( pasteString, "n");
        while( rowTokenizer.hasMoreTokens()) {
            rowClipboard++;
            String rowString = rowTokenizer.nextToken();
            StringTokenizer columnTokenizer = new StringTokenizer( rowString, "t");
            int colClipboard = -1;
            while( columnTokenizer.hasMoreTokens()) {
                colClipboard++;
                // get next cell data from clipboard
                String clipboardCellContent = columnTokenizer.nextToken();
                // calculate the position in the table cell
                int rowTable = pasteCellPosition.getRow() + rowClipboard;
                int colTable = pasteCellPosition.getColumn() + colClipboard;
                // skip if we reached the end of the table
                if( rowTable >= table.getItems().size()) {
                    continue;
                }
                if( colTable >= table.getColumns().size()) {
                    continue;
                }
                // System.out.println( rowClipboard + "/" + colClipboard + ": " + cell);
                // get cell
                TableColumn tableColumn = table.getVisibleLeafColumn(colTable);  // table position gives the view index => we need to operate on the view columns
                ObservableValue observableValue = tableColumn.getCellObservableValue(rowTable);
                System.out.println( rowTable + "/" + colTable + ": " +observableValue);
                // TODO: handle boolean, etc
                if( observableValue instanceof DoubleProperty) { 
                    try {
                        double value = numberFormatter.parse(clipboardCellContent).doubleValue();
                        ((DoubleProperty) observableValue).set(value);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
                else if( observableValue instanceof IntegerProperty) { 
                    try {
                        int value = NumberFormat.getInstance().parse(clipboardCellContent).intValue();
                        ((IntegerProperty) observableValue).set(value);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }                   
                else if( observableValue instanceof StringProperty) { 
                    ((StringProperty) observableValue).set(clipboardCellContent);
                } else {
                    System.out.println("Unsupported observable value: " + observableValue);
                }
                System.out.println(rowTable + "/" + colTable);
            }
        }
    }
}

从表数据中获取您想要的文本,并进行适当的格式化:然后

ClipboardContent content = new ClipboardContent();
content.putString(tableData);
Clipboard.getSystemClipboard().setContent(content);

最新更新