我需要使用poi将HashMaps转换为xlsx。对于工作表数据2,我需要这样的东西:
表格1:
但我有table2:
这是我的HashMaps列表:
行= [{kol2 = s,kol1 = s},{kol2 = bbbb,kol3 = bbbb,kol1 = aaaa},{kol2 = bbbb,kol3 = bbbb,kol1 = aaaa},{kol2 = bbbb,kol3 = bbbb, kol1 = aaaa},{kol2 = s,kol1 = s}]}
这是我的代码:
XSSFWorkbook workBook = new XSSFWorkbook();
XSSFSheet sheet = workBook.createSheet("data");
XSSFSheet sheet2 = workBook.createSheet("data2");
int rowCount = 0;
int help = 1;
List<HashMap<String, Object>> rows = ((List<HashMap<String, Object>>) x);
int rowCount2 = 0;
int header = 1;
Row header2 = sheet2.createRow(0);
for (int i = 0; i < rows.size(); i++) {
int li = 0;
Row row2 = sheet2.createRow(++rowCount2);
HashMap<String, Object> row = rows.get(i);
int columnCount2 = 0;
for (HashMap.Entry<String, Object> subElement : row.entrySet()) {
if (subElement.getValue() != null) {
if (i == li) {
Cell cell = header2.createCell(header);
cell.setCellValue(subElement.getKey().toString());
header++;
}
li++;
Cell cell2 = row2.createCell(++columnCount2);
cell2.setCellValue(subElement.getValue().toString());
}
}
}
有人可以帮忙吗?
最佳答案
遍历HashMap的EntrySet
第一个问题是您要遍历HashMap
的entrySet
for (HashMap.Entry<String, Object> subElement : row.entrySet()) {
// no guaranteed order
}
查看
Set#iterator()
方法的JavaDoc,您将看到:返回此集合中元素的迭代器。元素不按特定顺序返回(除非此集合是提供保证的某些类的实例)。
有些集是有序的(例如
TreeSet
),但是由于您使用的是HashMap
,因此您的EntrySet也将不会有序。请注意,工作表中的列顺序为kol2-kol3-kol1。您不希望它是kol1-kol2-kol3吗?
不创建空列
您忘记为地图中没有的列创建空单元格。
if (subElement.getValue() != null) {
// there won't be an empty cell if you e.g. don't have kol2 in your rows Map,
// since this just skips your current value
}
这就是为什么您会得到类似以下内容的原因:
kol2 kol3 kol1
s s
bbbb bbbb aaaa
...
代替:
kol2 kol3 kol1
s s
bbbb bbbb aaaa
...
在循环内创建标题行
通过在循环内创建标题行,您使解决方案变得比必要的更为复杂。仅创建标题行然后循环遍历
List
中的条目会容易得多。if (i == li) {
Cell cell = header2.createCell(header);
cell.setCellValue(subElement.getKey().toString());
header++;
}
如果在循环外执行此操作,则不需要
li
和header
变量建议的解决方案
我会(首先)想出类似这样的内容(我添加了一些通常不会在其中添加的注释,以便更清楚地说明意图是什么以及您需要了解解决方案的哪些方面):
XSSFSheet sheet2 = workBook.createSheet("data2");
List<HashMap<String, Object>> rows = ((List<HashMap<String, Object>>) x);
List<String> headers = Arrays.asList("kol1", "kol2", "kol3");
int currentRowNumber = 0;
// create header row
Row header = sheet2.createRow(currentRowNumber);
for (int i = 0; i < headers.size(); i++) {
Cell headerCell = header.createCell(i);
headerCell.setCellValue(headers.get(i));
}
// create data rows (we loop over the rows List)
for (int i = 0; i < rows.size(); i++) {
HashMap<String, Object> row = rows.get(i);
// we neet to increment the rowNumber for the row in the sheet at the beginning of
// each row. entry 0 in the rows List is in sheetRow 1, entry 1 in sheetRow 2, etc.
currentRowNumber++;
Row sheetRow = sheet2.createRow(currentRowNumber);
// we can now loop over the columns inside the row loop (using the headers List)
// we create a Cell for each column, but only fill it if there is
for (int j = 0; j < headers.size(); j++) {
Cell cell = sheetRow.createCell(j);
// only fill the cell if we are having data in the row map for the current column
String currentColumnName = headers.get(j);
if (row.containsKey(currentColumnName)) {
cell.setCellValue(row.get(currentColumnName).toString());
}
}
}
如果您想要不同的列顺序,只需更改标题列表即可(例如
Arrays.asList("kol2", "kol3", "kol1")
)。