0

Is it possible to copy jTable row and paste it into word document or in a new email with its formatted grid (colored horizontal and vertical grid lines).. If yes, how?

When I copy a row from jTable and paste it into word document, Word recognizes it as a table row but I have to style it by adding grid lines and coloring them

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
Wesamz
  • 57
  • 2
  • 8
  • 1
    There are two options that make this possible, but it would depend on the capabilities of the target. Your could for at the content as HTML, placing it within a HTML table or you could create a "text" based version of the rows (using -| + for example). The larger issue would be how to format the cells. The their option might be to render a snapshot of the row into a BufferedImage and export that – MadProgrammer Jul 26 '14 at 03:11
  • @MadProgrammer is there a method for getting the HTML version of an existing jTable? – Wesamz Jul 26 '14 at 19:14
  • No, you will have to write one, again,the problem is formatting the output of the data, as this is normally done by the TableCellRenderer which returns a Component, not text – MadProgrammer Jul 26 '14 at 21:28
  • @MadProgrammer sorry to bother you but one more question.. I used the following code for the copy button: Action copy = logtable.getActionMap().get("copy"); ActionEvent ae = new ActionEvent(logtable, ActionEvent.ACTION_PERFORMED, ""); copy.actionPerformed(ae); where logtable is my jTable.. where should I add the HTML code to draw the table of the copied data? – Wesamz Jul 27 '14 at 01:30

1 Answers1

7

This is a VERY simply example of copying a row of data into a HTML based table. I was able to copy any row and paste into word as a HTML based table without (to many) issues

CopyTable

CopyWord

import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringBufferInputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Vector;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;

public class CopyTable {

    public static void main(String[] args) {
        new CopyTable();
    }

    public CopyTable() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                DefaultTableModel model = new DefaultTableModel();
                for (int index = 0; index < 26; index++) {
                    model.addColumn((char) (index + 65));
                }

                for (int row = 0; row < 26; row++) {
                    Vector rowData = new Vector();
                    for (int col = 0; col < 26; col++) {
                        rowData.add(row + "x" + col);
                    }
                    model.addRow(rowData);
                }

                JTable table = new JTable(model);
                table.getActionMap().put("copy", new AbstractAction() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        int row = table.getSelectedRow();
                        StringBuilder sb = new StringBuilder(128);
                        sb.append("<table border=1 width=100%><tr>");
                        for (int col = 0; col < table.getColumnCount(); col++) {
                            sb.append("<td>");
                            sb.append(table.getValueAt(row, col).toString());
                            sb.append("</td>");
                        }
                        sb.append("</tr></table>");

                        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
                        clipboard.setContents(new HtmlSelection(sb.toString()), null);
                    }
                });

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JScrollPane(table));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    private static class HtmlSelection implements Transferable {

        private static ArrayList htmlFlavors = new ArrayList();

        static {

            try {

                htmlFlavors.add(new DataFlavor("text/html;class=java.lang.String"));

                htmlFlavors.add(new DataFlavor("text/html;class=java.io.Reader"));

                htmlFlavors.add(new DataFlavor("text/html;charset=unicode;class=java.io.InputStream"));

            } catch (ClassNotFoundException ex) {

                ex.printStackTrace();

            }

        }

        private String html;

        public HtmlSelection(String html) {

            this.html = html;

        }

        public DataFlavor[] getTransferDataFlavors() {

            return (DataFlavor[]) htmlFlavors.toArray(new DataFlavor[htmlFlavors.size()]);

        }

        public boolean isDataFlavorSupported(DataFlavor flavor) {

            return htmlFlavors.contains(flavor);

        }

        public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {

            if (String.class.equals(flavor.getRepresentationClass())) {

                return html;

            } else if (Reader.class.equals(flavor.getRepresentationClass())) {

                return new StringReader(html);

            } else if (InputStream.class.equals(flavor.getRepresentationClass())) {

                return new StringBufferInputStream(html);

            }

            throw new UnsupportedFlavorException(flavor);

        }

    }
}

This is very limited, as this will simply use each cell's toString method to get the value of the cell, this means that the cell value is not "formatted" according to the values type or application requirements. You're going to have to devise a solution for formatting the cell values to String yourself

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366