2015-07-29 2 views
1

Я начинаю разрабатывать в JavaFx, у меня есть проект, и я хочу знать, возможно ли сделать «копию-вставку» таблицы в javaFx. Я имею в виду, у меня есть TableView с некоторыми данными и просто хочу сохранить его в буфере обмена, чтобы экспортировать его в Microsoft Word или любой другой текстовый редактор. Это возможно? И как я могу это сделать? БлагодаряСохранить таблицу в clipboad javaFx

ответ

0

Вот пример о том, как вы можете копировать/вставить с помощью TableView. Вы должны расширить класс в соответствии с вашими типами свойств. Копировать/Вставить с и до. г. 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); 
      } 

     } 

    } 

} 
+0

спасибо! Я буду исследовать его –

+0

@Sredny M Casnanova: Я обновил код для поддержки html. Поэтому копирование в TableView и вставка в Word должно привести к тому, что Word будет иметь одну и ту же структуру таблицы. – Roland

0

Получить текст, который вы хотите из данных таблицы, отформатированных соответствующим образом: то вы можете сделать

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

все в порядке, я понимаю. Но еще одно, когда вы говорите «отформатировано соответствующим образом», это означает, что я только вставлю String в слово? Я хочу, чтобы это выглядело как стол. –

+0

Вы сказали, что хотите его в текстовом редакторе, поэтому вы можете обрабатывать только строковые данные. Вы можете, очевидно, форматировать его, чтобы столбцы были разделены вкладками и т. Д. –

Смежные вопросы