Jakarta POI
1
Jakarta POI (http://jakarta.apache.org/poi/index.html) jest zbiorem narzędzi
umożliwiającym prace z dokumentami zapisanymi w formatach wspieranych przez
Microsoft. W skład POI wchodzą następujące komponenty:
●
POIFS – obsługa dokumentów OLE 2,
●
HSSF – dokumenty w formacie Excel'a,
●
HWPF – proste dokumenty w formacie Word 97,
●
HPSF własności dokumentów OLE 2 (tytuł, autor, data ostatniej modyfikacji, ...).
HSSF w skrócie
2
●
odczyt i zapis arkusza:
POIFSFileSystem fs = new POIFSFileSystem(
new FileInputStream("input.xls"));
HSSFWorkbook wb = new HSSFWorkbook(fs);
FileOutputStream fileOut =
new FileOutputStream("output.xls");
wb.write(fileOut);
fileOut.close();
●
nowy, pusty dokument:
HSSFWorkbook wb = new HSSFWorkbook();
●
nowy arkusz:
HSSFSheet sheet1 = wb.createSheet("pierwszy arkusz");
HSSFSheet sheet2 = wb.createSheet("drugi arkusz");
HSSF w skrócie
3
●
dodawanie komórek do formularza:
HSSFRow row = sheet.createRow((short)0);
HSSFCell cell = row.createCell((short)0);
cell.setCellValue(1);
row.createCell((short)1).setCellValue("jakis tekst");
row.createCell((short)2).setCellValue(true);
●
daty
HSSFCell cell = row.createCell((short)3);
cell.setCellValue(new Date());
HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(
HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));
cell = row.createCell((short)4);
cell.setCellValue(new Date());
cell.setCellStyle(cellStyle);
HSSF w skrócie
4
●
justowanie:
HSSFCell cell = row.createCell((short)5);
cell.setCellValue("justowanie");
HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
cell.setCellStyle(cellStyle);
Więcej informacji: http://jakarta.apache.org/poi/hssf/quick-guide.html.
Przykład
5
Jako przykład zastosowania pakietu Jakarta POI przygotujemy klasę rozszerzającą
JTable
o metodę
public void exportTable(File file)
, która zapisuje
dane znajdujące się w tabeli do pliku
xls
.
1
A
Literka a
2
B
Literka b
3
C
Literka c
4
D
Literka d
JXMLTable
TableRow
TableRow.java
6
public
interface
TableRow {
public
Object getAttribute(
int
i);
public
void
setAttribute(
int
i, Object obj);
public
boolean
isEditable(
int
i);
}
Interfejs określa metody obiektu, który może być umieszczony w naszej tabeli.
TestObject.java
7
import
java.util.Date;
public
class
TestObject
implements
TableRow {
private
int
id
;
private
String
name
;
private
String
description
;
private
Date
date
;
public
TestObject(
int
i, String s1, String s2, Date d) {
this
.
id
= i;
this
.
name
= s1;
this
.
description
= s2;
this
.
date
= d;
}
public
boolean
isEditable(
int
i) {
if
(
this
.
id
> 0)
return
true
;
return
false
;
}
TestObject.java
8
public
Object getAttribute(
int
i) {
switch
(i) {
case
0:
return
new
Integer(
this
.
id
);
case
1:
return
this
.
name
;
case
2:
return
this
.
description
;
case
3:
return
this
.
date
;
default
:
return
null
;
}
}
TestObject.java
9
public
void
setAttribute(
int
i, Object obj) {
switch
(i) {
case
0:
if
(obj
instanceof
Integer) {
this
.
id
= ((Integer) obj).intValue();
}
break
;
case
1:
if
(obj
instanceof
String) {
this
.
name
= (String) obj;
}
break
;
case
2:
if
(obj
instanceof
String) {
this
.
description
= (String) obj;
}
break
;
case
3:
if
(obj
instanceof
Date) {
this
.
date
= (Date) obj;
}
break
;
default
:
}
return
;
}
}
Model tabeli
10
Dane, oraz inne informacje potrzebne do wyświetlenia tabeli
JTable
są zwykle
pamiętane w instancji klasy
JTableModel
. Pozwala to na rozdzielenie danych,
sposobu prezentacji i widoku.
Model
TableModel
Widok
JTable
XSLTableModel.java
11
i
import
javax.swing.table.AbstractTableModel;
public
class
XLSTableModel
extends
AbstractTableModel {
private
static
final
int
columnCount
= 4;
private
static
final
int
[]
columnWidths
= { 100, 150, 100, 50 };
private
static
final
String[]
columnNames
= {
"pierwsza"
,
"druga"
,
"trzecia"
,
"czwarta"
};
private
static
final
String[]
columnTips
= {
"pierwsza kolumna"
,
"druga kolumna"
,
"trzecia kolumna"
,
"czwarta kolumna"
};
private
TableRow[]
rows
;
public
XLSTableModel(TableRow[] tra) {
super
();
this
.
rows
= tra;
}
public
void
update(TableRow[] tra) {
this
.
rows
= tra;
}
public
TableRow getObjectAt(
int
rowIndex) {
if
(rowIndex >= 0 && rowIndex >
this
.
rows
.
length
)
return
this
.
rows
[rowIndex];
return
null
;
}
XSLTableModel.java
12
public
int
getRowCount() {
return
this
.
rows
.
length
;
}
public
int
getColumnCount() {
return
columnCount
;
}
public
String getColumnName(
int
i) {
return
columnNames
[i];
}
public
Class getColumnClass(
int
i) {
if
(
this
.
rows
.
length
> 0) {
return
this
.
rows
[0].getAttribute(i).getClass();
}
return
String.
class
;
}
public
int
getColumnWidth(
int
i) {
return
columnWidths
[i];
}
XSLTableModel.java
13
public
String getColumnTip(
int
i) {
return
columnTips
[i];
}
public
boolean
isCellEditable(
int
row,
int
column) {
TableRow tr =
this
.
rows
[row];
if
(tr !=
null
)
return
tr.isEditable(column);
return
false
;
}
public
Object getValueAt(
int
row,
int
column) {
TableRow tr =
this
.
rows
[row];
if
(tr !=
null
)
return
tr.getAttribute(column);
return
null
;
}
public
void
setValueAt(Object aValue,
int
row,
int
column) {
Object obj = getValueAt(row, column);
if
(aValue ==
null
|| aValue.equals(obj))
return
;
TableRow tr =
this
.
rows
[row];
tr.setAttribute(column, aValue);
}
}
JXLSTable.java
14
...
import
org.apache.poi.hssf.usermodel.HSSFCell;
import
org.apache.poi.hssf.usermodel.HSSFRow;
import
org.apache.poi.hssf.usermodel.HSSFSheet;
import
org.apache.poi.hssf.usermodel.HSSFWorkbook;
public
class
JXLSTable
extends
JTable {
protected
JTableHeader createDefaultTableHeader() {
return
new
JTableHeader(
this
.
columnModel
) {
public
String getToolTipText(MouseEvent e) {
Point p = e.getPoint();
int
index =
this
.
columnModel
.getColumnIndexAtX(p.
x
);
if
(index < 0)
return
null
;
int
realIndex =
this
.
columnModel
.getColumn(index)
.getModelIndex();
return
((XLSTableModel) JXLSTable.
this
.getModel())
.getColumnTip(realIndex);
}
};
}
JXLSTable.java
15
public
JXLSTable(TableRow[] ta) {
super
();
this
.setModel(
new
XLSTableModel(ta));
}
public
void
exportTable(File file) {
int
iRow, iColumn, i;
Object obj;
TableCellRenderer r;
Component c;
String sTmp;
HSSFRow row;
HSSFCell cell;
HSSFWorkbook workbook =
new
HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet();
TableModel tm =
this
.getModel();
row = sheet.createRow(sheet.getPhysicalNumberOfRows());
for
(iColumn=0, i=0; iColumn<tm.getColumnCount(); iColumn++) {
sTmp = tm.getColumnName(iColumn);
if
(sTmp ==
null
)
sTmp =
""
;
cell = row.createCell((
short
) i);
cell.setEncoding(HSSFCell.
ENCODING_UTF_16
);
cell.setCellValue(sTmp);
i++;
}
JXLSTable.java
16
for
(iRow = 0; iRow < tm.getRowCount(); iRow++) {
row = sheet.createRow(sheet.getPhysicalNumberOfRows());
for
(iColumn=0, i=0; iColumn<tm.getColumnCount(); iColumn++){
cell = row.createCell((
short
) i);
obj = tm.getValueAt(iRow, iColumn);
sTmp =
""
;
if
(obj !=
null
) {
r =
this
.getCellRenderer(iRow, iColumn);
c =
this
.prepareRenderer(r, iRow, iColumn);
if
(c !=
null
) {
if
(c
instanceof
JLabel)
sTmp = ((JLabel) c).getText();
else
sTmp = obj.toString();
}
// if c
}
// if obj
cell.setEncoding(HSSFCell.
ENCODING_UTF_16
);
cell.setCellValue(sTmp);
i++;
}
// for
}
// for
JXLSTable.java
17
try
{
FileOutputStream fos =
new
FileOutputStream(file);
workbook.write(fos);
fos.close();
}
catch
(IOException e) {
e.printStackTrace();
}
}
}
Example.java
18
Klasa
Example
służy do przetestowania przygotowanego pakietu narzędzi:
import
...
public
class
Example
implements
ActionListener {
private
JXLSTable
table
;
private
JTextField
filename
;
public
static
void
main(String[] args) {
TestObject[] toa =
new
TestObject[4];
toa[0] =
new
TestObject(1,
"a"
,
"literka a"
,
new
Date());
toa[1] =
new
TestObject(2,
"b"
,
"literka b"
,
new
Date());
toa[2] =
new
TestObject(3,
"c"
,
"literka c"
,
new
Date());
toa[3] =
new
TestObject(4,
"d"
,
"literka d"
,
new
Date());
JXLSTable table =
new
JXLSTable(toa);
JScrollPane sp =
new
JScrollPane(table);
JTextField tf =
new
JTextField(
"output.xls"
);
Example ex =
new
Example();
ex.
filename
= tf;
ex.
table
= table;
Example.java
19
JButton b =
new
JButton(
"Export"
);
b.setActionCommand(
"export"
);
b.addActionListener(ex);
JPanel p =
new
JPanel(
new
BorderLayout());
p.add(tf, BorderLayout.
NORTH
);
p.add(sp, BorderLayout.
CENTER
);
p.add(b, BorderLayout.
SOUTH
);
JFrame f =
new
JFrame(
"XLSExample"
);
f.getContentPane().add(p);
f.pack();
f.setLocationRelativeTo(
null
);
f.setDefaultCloseOperation(JFrame.
EXIT_ON_CLOSE
);
f.setVisible(
true
);
}
public
void
actionPerformed(ActionEvent ae) {
if
(ae.getActionCommand().equals(
"export"
)) {
this
.
table
.exportTable(
new
File(
this
.
filename
.getText()));
JOptionPane.showMessageDialog(
null
,
"plik zosta\u0142 zapisany"
,
"Informacja"
, JOptionPane.
INFORMATION_MESSAGE
);
}
}
}
Uruchomienie programu
20
●
do ścieżki klas należy dodać bibliotekę
poi-2.0-final-20040126.jar
●
kompilacja i uruchomienie za pomocą komend
javac
i
java
.
Podsumowanie
21
Dzięki różnorodnym bibliotekom programy napisane w Javie mogą obsługiwać
wiele formatów dokumentów. Projekt Jakarta POI jest jednym z przykładów takiej
powszechnie wykorzystywanej, biblioteki.