Apache POI:找出溢出到下一列的文本的 colspan
Apache POI: Find out colspan of text overflowing to next column
我正在使用 Apache POI 将 Excel 转换为 HTML。我希望 HTML table 与 Excel 中显示的完全一样。我经常看到 Excel 单元格中的数据溢出到下一列的情况。有没有办法找出数据跨越多少列,以便我可以将 colspan
属性添加到 TD
标记?请参阅来自 Excel 的屏幕截图:
在这种情况下,单元格A2中的数据溢出到单元格B2(也是A3溢出到B3)。有没有办法查到A2单元格对应的TD标签需要colspan="2"
属性?
数据溢出的单元格没有合并所以我不能真正使用像sheet.getNumMergedRegions()
这样的函数
我想如果我能以某种方式找出 Excel 中列的 "visible" 宽度,我想我也可以计算它。但是,sheet.getColumnWidth()
仅提供实际宽度。我没有看到找出 Excel 中列的 "visible" 宽度的方法。在上面的屏幕截图 link 中,A 列的可见宽度非常小。有没有办法找到 "visible" 宽度?
我正在使用 Apache POI 3.17
Apache poi
可以根据内容自动调整列的大小。所以它需要能够计算特殊内容需要的列宽。这就是 SheetUtil.getCellWidth 正在做的事情。
此外,还需要知道 Microsoft
在 Excel
中为列宽引入的非常特殊的测量单位。例如,在 Excel
s GUI
中,列宽为 10 表示单元格宽度可容纳 10 个默认字符宽度的字符。但在内部,宽度是以默认字符宽度的 1/256 为单位计算的。这就是 apache poi
决定以字符宽度的 1/256 为单位得到 Sheet.getColumnWidth 的原因。
因此,如果您有 Cell cell
单元格索引 c
和特殊内容,则使用
Workbook workbook...
...
DataFormatter dataFormatter = new DataFormatter();
...
int defaultCharWidth = SheetUtil.getDefaultCharWidth(workbook);
...
double cellValueWidth = SheetUtil.getCellWidth(cell, defaultCharWidth, dataFormatter, false);
int neededColunmnWidth = (int)cellValueWidth*256;
int columnWidth = sheet.getColumnWidth(c);
...
您可以确定内容是否适合单元格。如果 columnWidth >= neededColunmnWidth
适合,否则不适合,必须使用 colspan
。
来一个完整的例子来说明原理:
Sheet:
代码:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.SheetUtil;
import java.io.*;
class ExcelToHTMLColspan {
public static void main(String[] args) throws Exception{
Workbook workbook = WorkbookFactory.create(new FileInputStream("Test.xlsx"));
DataFormatter dataFormatter = new DataFormatter();
int defaultCharWidth = SheetUtil.getDefaultCharWidth(workbook);
int lastColumnToExport = 5; // column E
Sheet sheet = workbook.getSheetAt(0);
Row row;
Cell cell;
String cellValue;
StringBuilder tableHTML = new StringBuilder();
tableHTML.append("<TABLE>");
tableHTML.append("<COLGROUP>");
for (int c = 0; c < lastColumnToExport; c++) {
long columnWidthPx = Math.round(sheet.getColumnWidthInPixels(c));
tableHTML.append("<COL width=\"" + columnWidthPx + "\"/>");
}
tableHTML.append("</COLGROUP>");
for (int r = 0; r <= sheet.getLastRowNum(); r++) {
row = sheet.getRow(r); if (row == null) row = sheet.createRow(r);
long rowHeightPx = Math.round(row.getHeightInPoints() * 92f / 72f);
tableHTML.append("<TR height=\"" + rowHeightPx + "\">");
int c = 0;
while(c < lastColumnToExport) {
tableHTML.append("<TD");
cell = row.getCell(c); if (cell == null) cell = row.createCell(c);
cellValue = dataFormatter.formatCellValue(cell);
double cellValueWidth = SheetUtil.getCellWidth(cell, defaultCharWidth, dataFormatter, false);
int neededColunmnWidth = (int)cellValueWidth*256;
int columnWidth = sheet.getColumnWidth(c);
if (columnWidth < neededColunmnWidth) {
int colSpan = 1;
while(columnWidth < neededColunmnWidth) {
colSpan++;
c++;
columnWidth += sheet.getColumnWidth(c);
}
tableHTML.append(" colspan=\"" + colSpan + "\"" + ">" + cellValue);
c++;
} else {
tableHTML.append(">" + cellValue);
c++;
}
tableHTML.append("</TD>");
}
tableHTML.append("</TR>");
}
tableHTML.append("</TABLE>");
workbook.close();
System.out.println(tableHTML.toString());
//creating a sample HTML file
String encoding = "UTF-8";
FileOutputStream fos = new FileOutputStream("result.html");
OutputStreamWriter writer = new OutputStreamWriter(fos, encoding);
writer.write("<!DOCTYPE html>\n");
writer.write("<html lang=\"en\">");
writer.write("<head>");
writer.write("<meta charset=\"utf-8\"/>");
writer.write("<style>");
writer.write("table {border-collapse: collapse; table-layout: fixed;}");
writer.write("table, tr, td {border: 1px solid black;}");
writer.write("td {font: 11pt Calibri, arial, sans-serif;}");
writer.write("</style>");
writer.write("</head>");
writer.write("<body>");
writer.write(tableHTML.toString());
writer.write("</body>");
writer.write("</html>");
writer.close();
java.awt.Desktop.getDesktop().browse(new File("result.html").toURI());
}
}
结果:
我正在使用 Apache POI 将 Excel 转换为 HTML。我希望 HTML table 与 Excel 中显示的完全一样。我经常看到 Excel 单元格中的数据溢出到下一列的情况。有没有办法找出数据跨越多少列,以便我可以将 colspan
属性添加到 TD
标记?请参阅来自 Excel 的屏幕截图:
在这种情况下,单元格A2中的数据溢出到单元格B2(也是A3溢出到B3)。有没有办法查到A2单元格对应的TD标签需要colspan="2"
属性?
数据溢出的单元格没有合并所以我不能真正使用像sheet.getNumMergedRegions()
我想如果我能以某种方式找出 Excel 中列的 "visible" 宽度,我想我也可以计算它。但是,sheet.getColumnWidth()
仅提供实际宽度。我没有看到找出 Excel 中列的 "visible" 宽度的方法。在上面的屏幕截图 link 中,A 列的可见宽度非常小。有没有办法找到 "visible" 宽度?
我正在使用 Apache POI 3.17
Apache poi
可以根据内容自动调整列的大小。所以它需要能够计算特殊内容需要的列宽。这就是 SheetUtil.getCellWidth 正在做的事情。
此外,还需要知道 Microsoft
在 Excel
中为列宽引入的非常特殊的测量单位。例如,在 Excel
s GUI
中,列宽为 10 表示单元格宽度可容纳 10 个默认字符宽度的字符。但在内部,宽度是以默认字符宽度的 1/256 为单位计算的。这就是 apache poi
决定以字符宽度的 1/256 为单位得到 Sheet.getColumnWidth 的原因。
因此,如果您有 Cell cell
单元格索引 c
和特殊内容,则使用
Workbook workbook...
...
DataFormatter dataFormatter = new DataFormatter();
...
int defaultCharWidth = SheetUtil.getDefaultCharWidth(workbook);
...
double cellValueWidth = SheetUtil.getCellWidth(cell, defaultCharWidth, dataFormatter, false);
int neededColunmnWidth = (int)cellValueWidth*256;
int columnWidth = sheet.getColumnWidth(c);
...
您可以确定内容是否适合单元格。如果 columnWidth >= neededColunmnWidth
适合,否则不适合,必须使用 colspan
。
来一个完整的例子来说明原理:
Sheet:
代码:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.SheetUtil;
import java.io.*;
class ExcelToHTMLColspan {
public static void main(String[] args) throws Exception{
Workbook workbook = WorkbookFactory.create(new FileInputStream("Test.xlsx"));
DataFormatter dataFormatter = new DataFormatter();
int defaultCharWidth = SheetUtil.getDefaultCharWidth(workbook);
int lastColumnToExport = 5; // column E
Sheet sheet = workbook.getSheetAt(0);
Row row;
Cell cell;
String cellValue;
StringBuilder tableHTML = new StringBuilder();
tableHTML.append("<TABLE>");
tableHTML.append("<COLGROUP>");
for (int c = 0; c < lastColumnToExport; c++) {
long columnWidthPx = Math.round(sheet.getColumnWidthInPixels(c));
tableHTML.append("<COL width=\"" + columnWidthPx + "\"/>");
}
tableHTML.append("</COLGROUP>");
for (int r = 0; r <= sheet.getLastRowNum(); r++) {
row = sheet.getRow(r); if (row == null) row = sheet.createRow(r);
long rowHeightPx = Math.round(row.getHeightInPoints() * 92f / 72f);
tableHTML.append("<TR height=\"" + rowHeightPx + "\">");
int c = 0;
while(c < lastColumnToExport) {
tableHTML.append("<TD");
cell = row.getCell(c); if (cell == null) cell = row.createCell(c);
cellValue = dataFormatter.formatCellValue(cell);
double cellValueWidth = SheetUtil.getCellWidth(cell, defaultCharWidth, dataFormatter, false);
int neededColunmnWidth = (int)cellValueWidth*256;
int columnWidth = sheet.getColumnWidth(c);
if (columnWidth < neededColunmnWidth) {
int colSpan = 1;
while(columnWidth < neededColunmnWidth) {
colSpan++;
c++;
columnWidth += sheet.getColumnWidth(c);
}
tableHTML.append(" colspan=\"" + colSpan + "\"" + ">" + cellValue);
c++;
} else {
tableHTML.append(">" + cellValue);
c++;
}
tableHTML.append("</TD>");
}
tableHTML.append("</TR>");
}
tableHTML.append("</TABLE>");
workbook.close();
System.out.println(tableHTML.toString());
//creating a sample HTML file
String encoding = "UTF-8";
FileOutputStream fos = new FileOutputStream("result.html");
OutputStreamWriter writer = new OutputStreamWriter(fos, encoding);
writer.write("<!DOCTYPE html>\n");
writer.write("<html lang=\"en\">");
writer.write("<head>");
writer.write("<meta charset=\"utf-8\"/>");
writer.write("<style>");
writer.write("table {border-collapse: collapse; table-layout: fixed;}");
writer.write("table, tr, td {border: 1px solid black;}");
writer.write("td {font: 11pt Calibri, arial, sans-serif;}");
writer.write("</style>");
writer.write("</head>");
writer.write("<body>");
writer.write(tableHTML.toString());
writer.write("</body>");
writer.write("</html>");
writer.close();
java.awt.Desktop.getDesktop().browse(new File("result.html").toURI());
}
}
结果: