如何将 'xls' 文件中的 2 行 header 转换为单行 header?
How to convert a 2 rows header into a single row header from a 'xls' file?
我正在尝试从一个 excel 文件创建一个 header,该文件在两个不同的行上有 table header。我必须从这两个中创建一个 header 行。
我采用的方法是将 @ 附加到第一个 header 并尝试用第二个 header 值替换它。
我的 excel 文件看起来像这样
Bank Positive Name of Local Approah
Value Customer Civilian Remote
//some data
这是我使用的代码
public List<String> processSheet(Sheet sheet) {
ActivityLauncher.logConsoleMsg("Processing sheet " + sheet.getSheetName() + " started");
List<String> rows = new ArrayList<String>();
Iterator<Row> rowIterator = sheet.iterator();
List<String>firstHeader = new ArrayList<String>();
List<String>secondHeader = new ArrayList<String>();
List<String>finalHeader = new ArrayList<String>();
while (rowIterator.hasNext()) {
Row currentRow = rowIterator.next();
StringBuilder row = new StringBuilder();
for (int i = 0; i < currentRow.getLastCellNum(); i++) {
if(currentRow.getRowNum()==0 || currentRow.getRowNum()==1 || currentRow.getRowNum()==3 || currentRow.getRowNum()==2) {
continue;
} else {
Cell currentCell = currentRow.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
String cellValue = excelManager.evalCell(currentCell);
//inserting the alternate row into the text file to make a continues header
if(currentCell.getRowIndex()==4 ) {
if(cellValue.equals("Local Risk")) {
row.append(cellValue);
row.append("@");
break;
} else {
row.append(cellValue);
row.append("@");
}
}
if(currentCell.getRowIndex()==5) {
if(cellValue.equals("rating")) {
row.append(cellValue);
row.append("@");
break;
} else {
int pos = row.indexOf("@");
if(pos >=0) {
row.replace(pos, 1, cellValue);
}
}
}
}
}
if (!row.toString().isEmpty()) {
rows.add(row.toString());
}
}
ActivityLauncher.logConsoleMsg("Processing sheet " + sheet.getSheetName() + " completed");
return rows;
}
目前,我得到这个输出:
Bank@Positive@Name of@Local Approah@
Value Customer Civilian Remote
但我的目标是
Bank Value Positive Customer Name of Civilian Approach Remote
有人可以帮我解决这个问题吗?
row.toString().replaceAll("@", cellValue);
无效,因为在调用 toString
和后续替换后获得的字符串被丢弃并被垃圾收集。
如果要进行就地替换,请使用 indexOf
和 replace(int,int,String)
:
int pos = row.indexOf("@");
if (pos >= 0) {
row.replace(pos, pos+1, cellValue);
}
此外,当您扫描与插入 '@'
个字符不同的行时,必须进行替换,因此您需要确保第 4 行 StringBuilder
"survives" 当你进入第 5 行时。为了使其工作,在循环外声明 row
,并且仅当当前行不等于 4 时才用新的替换它:
StringBuilder row = new StringBuilder();
while (rowIterator.hasNext()) {
Row currentRow = rowIterator.next();
...
if (currentCell.getRowIndex() == 4) {
continue;
}
if (!row.toString().isEmpty()) {
rows.add(row.toString());
row = new StringBuilder();
}
}
外部 link fiddle :
Here is a fiddle 我用 hard-coded 数据制作的数据与下面的例子使用了几乎相同的算法。
对于header,您最好制作一个包含两行的列表,并在完成后追加字符串。
试试这个代码:
public List<String> processSheet(Sheet sheet) {
List<String> headers = new ArrayList<>();
Iterator<Row> rowIterator = sheet.iterator();
int rowCnt = 0;
while (rowIterator.hasNext()) {
Row currentRow = rowIterator.next();
for (int i = 0; i < currentRow.getLastCellNum(); ++i) {
Cell currentCell = currentRow.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
String cellValue = excelManager.evalCell(currentCell);
headers.add(rowCnt + (i * (rowCnt+1)), cellValue);
}
++rowCnt;
}
return headers;
}
此算法适用于任意数量的行和任意数量的列,只要每行的列数相同即可。 here's a fiddle 和 hard-coded 遵循相同算法的示例数据。完成后,您可以 2 乘 2 地追加字符串(如果 header 有 3 行高,则可以追加 3 乘 3)。像这样的算法应该没问题:
private static List<String> appendStrings(List<String> original, int group) throws Exception {
if (original.size() % group == 0) {
List<String> newList = new ArrayList<>();
for (int i = 0; i < original.size(); i += group) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < group; ++j) {
if (sb.length() > 0) {
sb.append(" ");
}
sb.append(original.get(i + j));
}
newList.add(sb.toString());
}
return newList;
} else {
throw new Exception("MyClass::appendStrings() ---> the group value must be a factor of the size of the original list");
}
}
如果您的行可能包含空单元格并且您不希望添加空字符串,但仍希望遵守顺序,则需要在生成列表后删除数据。像这样:
public List<String> processSheet(Sheet sheet) {
/*... same code as previous example ...*/
// the following removes all "" or null values
while(headers.remove(null) || headers.remove("")){}
return headers;
}
我正在尝试从一个 excel 文件创建一个 header,该文件在两个不同的行上有 table header。我必须从这两个中创建一个 header 行。
我采用的方法是将 @ 附加到第一个 header 并尝试用第二个 header 值替换它。
我的 excel 文件看起来像这样
Bank Positive Name of Local Approah
Value Customer Civilian Remote
//some data
这是我使用的代码
public List<String> processSheet(Sheet sheet) {
ActivityLauncher.logConsoleMsg("Processing sheet " + sheet.getSheetName() + " started");
List<String> rows = new ArrayList<String>();
Iterator<Row> rowIterator = sheet.iterator();
List<String>firstHeader = new ArrayList<String>();
List<String>secondHeader = new ArrayList<String>();
List<String>finalHeader = new ArrayList<String>();
while (rowIterator.hasNext()) {
Row currentRow = rowIterator.next();
StringBuilder row = new StringBuilder();
for (int i = 0; i < currentRow.getLastCellNum(); i++) {
if(currentRow.getRowNum()==0 || currentRow.getRowNum()==1 || currentRow.getRowNum()==3 || currentRow.getRowNum()==2) {
continue;
} else {
Cell currentCell = currentRow.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
String cellValue = excelManager.evalCell(currentCell);
//inserting the alternate row into the text file to make a continues header
if(currentCell.getRowIndex()==4 ) {
if(cellValue.equals("Local Risk")) {
row.append(cellValue);
row.append("@");
break;
} else {
row.append(cellValue);
row.append("@");
}
}
if(currentCell.getRowIndex()==5) {
if(cellValue.equals("rating")) {
row.append(cellValue);
row.append("@");
break;
} else {
int pos = row.indexOf("@");
if(pos >=0) {
row.replace(pos, 1, cellValue);
}
}
}
}
}
if (!row.toString().isEmpty()) {
rows.add(row.toString());
}
}
ActivityLauncher.logConsoleMsg("Processing sheet " + sheet.getSheetName() + " completed");
return rows;
}
目前,我得到这个输出:
Bank@Positive@Name of@Local Approah@
Value Customer Civilian Remote
但我的目标是
Bank Value Positive Customer Name of Civilian Approach Remote
有人可以帮我解决这个问题吗?
row.toString().replaceAll("@", cellValue);
无效,因为在调用 toString
和后续替换后获得的字符串被丢弃并被垃圾收集。
如果要进行就地替换,请使用 indexOf
和 replace(int,int,String)
:
int pos = row.indexOf("@");
if (pos >= 0) {
row.replace(pos, pos+1, cellValue);
}
此外,当您扫描与插入 '@'
个字符不同的行时,必须进行替换,因此您需要确保第 4 行 StringBuilder
"survives" 当你进入第 5 行时。为了使其工作,在循环外声明 row
,并且仅当当前行不等于 4 时才用新的替换它:
StringBuilder row = new StringBuilder();
while (rowIterator.hasNext()) {
Row currentRow = rowIterator.next();
...
if (currentCell.getRowIndex() == 4) {
continue;
}
if (!row.toString().isEmpty()) {
rows.add(row.toString());
row = new StringBuilder();
}
}
外部 link fiddle :
Here is a fiddle 我用 hard-coded 数据制作的数据与下面的例子使用了几乎相同的算法。
对于header,您最好制作一个包含两行的列表,并在完成后追加字符串。
试试这个代码:
public List<String> processSheet(Sheet sheet) {
List<String> headers = new ArrayList<>();
Iterator<Row> rowIterator = sheet.iterator();
int rowCnt = 0;
while (rowIterator.hasNext()) {
Row currentRow = rowIterator.next();
for (int i = 0; i < currentRow.getLastCellNum(); ++i) {
Cell currentCell = currentRow.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
String cellValue = excelManager.evalCell(currentCell);
headers.add(rowCnt + (i * (rowCnt+1)), cellValue);
}
++rowCnt;
}
return headers;
}
此算法适用于任意数量的行和任意数量的列,只要每行的列数相同即可。 here's a fiddle 和 hard-coded 遵循相同算法的示例数据。完成后,您可以 2 乘 2 地追加字符串(如果 header 有 3 行高,则可以追加 3 乘 3)。像这样的算法应该没问题:
private static List<String> appendStrings(List<String> original, int group) throws Exception {
if (original.size() % group == 0) {
List<String> newList = new ArrayList<>();
for (int i = 0; i < original.size(); i += group) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < group; ++j) {
if (sb.length() > 0) {
sb.append(" ");
}
sb.append(original.get(i + j));
}
newList.add(sb.toString());
}
return newList;
} else {
throw new Exception("MyClass::appendStrings() ---> the group value must be a factor of the size of the original list");
}
}
如果您的行可能包含空单元格并且您不希望添加空字符串,但仍希望遵守顺序,则需要在生成列表后删除数据。像这样:
public List<String> processSheet(Sheet sheet) {
/*... same code as previous example ...*/
// the following removes all "" or null values
while(headers.remove(null) || headers.remove("")){}
return headers;
}