【问题标题】:Save table in clipboad javaFx在剪贴板 javaFx 中保存表格
【发布时间】:2015-07-29 18:53:54
【问题描述】:

我开始使用 JavaFx 进行开发,我有一个项目,我想知道是否可以在 javaFx 中创建一个表的“复制粘贴”。我的意思是,我有一个包含一些数据的 TableView,只是想将其保存在剪贴板中以将其导出到 Microsoft Word 或任何其他文本编辑器。这可能吗?我该怎么做?谢谢

【问题讨论】:

    标签: java javafx tableview clipboard


    【解决方案1】:

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

    一种改进的解决方案是使用混合剪贴板内容,以便将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() + "\n\nhtml:\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);
                }
    
            }
    
        }
    
    }
    

    【讨论】:

    • @Sredny M Casnanova:我更新了代码以支持 html。因此,在 TableView 中复制并粘贴到 Word 中应该会导致 Word 具有相同的表结构。
    【解决方案2】:

    从表格数据中获取你想要的文本,格式适当:然后你就可以了

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

    【讨论】:

    • 好吧,我明白了。但是还有一件事,当您说“适当格式化”时,这意味着我只会将字符串粘贴到 word 中?我希望它看起来像一张桌子。
    • 您说您希望在文本编辑器中使用它,因此您只能处理字符串数据。您显然可以对其进行格式化,以便列由制表符等分隔。
    猜你喜欢
    • 2022-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多