使用poi將excel轉爲html,如果需要表格可編輯,可以讓你們前端給提供樣式設置到代碼裏,碼雲代碼庫位置poiexample,歡迎來豐富它的功能
poi版本 4.1.2
pom依賴
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
使用方法:
main方法調用測試:
public class Tmp {
public static void main(String[] args) throws Exception {
String arg1 = "C:\\Users\\test.xlsx";
StringBuilder stringBuilder = new StringBuilder();
// 打印實現Appendable 接口,可打印到stringbuilder、stringbuffer、BufferedWriter等
ExcelToHtml excelToHtml = ExcelToHtml.create(arg1, stringBuilder);
excelToHtml.setCompleteHTML(true);// 是否打印完整html
excelToHtml.printPage();// 打印
System.out.println(stringBuilder.toString());// 輸出打印結果
}
}
下面幾個工具文件:
ExcelToHtml.java 主要操作方法類
HtmlHelper.java 幫助類接口
HSSFHtmlHelper.java 97-2007版本excel實現幫助類
XSSFHtmlHelper.java 新版本excel實現幫助類
ExcelToHtml.java:
package com.demo.exceltohtml;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.format.CellFormat;
import org.apache.poi.ss.format.CellFormatResult;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
import java.util.*;
public class ExcelToHtml {
private final Workbook wb;
private final Appendable output;
private boolean completeHTML;
private Formatter out;
private boolean gotBounds;
private int firstColumn;
private int endColumn;
private HtmlHelper helper;
private static final String DEFAULTS_CLASS = "excelDefaults";
private static final String COL_HEAD_CLASS = "colHeader";
private static final String ROW_HEAD_CLASS = "rowHeader";
private static final Map<HorizontalAlignment, String> HALIGN = mapFor(
HorizontalAlignment.LEFT, "left",
HorizontalAlignment.CENTER, "center",
HorizontalAlignment.RIGHT, "right",
HorizontalAlignment.FILL, "left",
HorizontalAlignment.JUSTIFY, "left",
HorizontalAlignment.CENTER_SELECTION, "center");
private static final Map<VerticalAlignment, String> VALIGN = mapFor(
VerticalAlignment.BOTTOM, "bottom",
VerticalAlignment.CENTER, "middle",
VerticalAlignment.TOP, "top");
private static final Map<BorderStyle, String> BORDER = mapFor(
BorderStyle.DASH_DOT, "dashed 1pt",
BorderStyle.DASH_DOT_DOT, "dashed 1pt",
BorderStyle.DASHED, "dashed 1pt",
BorderStyle.DOTTED, "dotted 1pt",
BorderStyle.DOUBLE, "double 3pt",
BorderStyle.HAIR, "solid 1px",
BorderStyle.MEDIUM, "solid 2pt",
BorderStyle.MEDIUM_DASH_DOT, "dashed 2pt",
BorderStyle.MEDIUM_DASH_DOT_DOT, "dashed 2pt",
BorderStyle.MEDIUM_DASHED, "dashed 2pt",
BorderStyle.NONE, "none",
BorderStyle.SLANTED_DASH_DOT, "dashed 2pt",
BorderStyle.THICK, "solid 3pt",
BorderStyle.THIN, "dashed 1pt");
private static final int IDX_TABLE_WIDTH = -2;
private static final int IDX_HEADER_COL_WIDTH = -1;
@SuppressWarnings({"unchecked"})
private static <K, V> Map<K, V> mapFor(Object... mapping) {
Map<K, V> map = new HashMap<>();
for (int i = 0; i < mapping.length; i += 2) {
map.put((K) mapping[i], (V) mapping[i + 1]);
}
return map;
}
public static ExcelToHtml create(Workbook wb, Appendable output) {
return new ExcelToHtml(wb, output);
}
public static ExcelToHtml create(String path, Appendable output)
throws IOException {
return create(new FileInputStream(path), output);
}
public static ExcelToHtml create(InputStream in, Appendable output)
throws IOException {
Workbook wb = WorkbookFactory.create(in);
return create(wb, output);
}
private ExcelToHtml(Workbook wb, Appendable output) {
if (wb == null) {
throw new NullPointerException("wb");
}
if (output == null) {
throw new NullPointerException("output");
}
this.wb = wb;
this.output = output;
setupColorMap();
}
private void setupColorMap() {
if (wb instanceof HSSFWorkbook) {
helper = new HSSFHtmlHelper((HSSFWorkbook) wb);
} else if (wb instanceof XSSFWorkbook) {
helper = new XSSFHtmlHelper();
} else {
throw new IllegalArgumentException(
"unknown workbook type: " + wb.getClass().getSimpleName());
}
}
public void setCompleteHTML(boolean completeHTML) {
this.completeHTML = completeHTML;
}
public void printPage() throws IOException {
try {
ensureOut();
if (completeHTML) {
out.format(
"<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>%n");
out.format("<html>%n");
out.format("<head>%n");
out.format("</head>%n");
out.format("<body>%n");
}
print();
if (completeHTML) {
out.format("</body>%n");
out.format("</html>%n");
}
} finally {
IOUtils.closeQuietly(out);
if (output instanceof Closeable) {
IOUtils.closeQuietly((Closeable) output);
}
}
}
public void print() {
printInlineStyle();
printSheets();
}
private void printInlineStyle() {
//out.format("<link href=\"excelStyle.css\" rel=\"stylesheet\" type=\"text/css\">%n");
out.format("<style type=\"text/css\">%n");
printStyles();
out.format("</style>%n");
}
private void ensureOut() {
if (out == null) {
out = new Formatter(output);
}
}
public void printStyles() {
ensureOut();
// First, copy the base css
out.format(".excelDefaults {%n");
out.format(" background-color: white;%n");
out.format(" color: black;%n");
out.format(" text-decoration: none;%n");
out.format(" direction: ltr;%n");
out.format(" text-transform: none;%n");
out.format(" text-indent: 0;%n");
out.format(" letter-spacing: 0;%n");
out.format(" word-spacing: 0;%n");
out.format(" white-space: pre-wrap;%n");
out.format(" unicode-bidi: normal;%n");
out.format(" vertical-align: 0;%n");
out.format(" background-image: none;%n");
out.format(" text-shadow: none;%n");
out.format(" list-style-image: none;%n");
out.format(" list-style-type: none;%n");
out.format(" padding: 0;%n");
out.format(" margin: 0;%n");
out.format(" border-collapse: collapse;%n");
out.format(" vertical-align: bottom;%n");
out.format(" font-style: normal;%n");
out.format(" font-family: sans-serif;%n");
out.format(" font-variant: normal;%n");
out.format(" font-weight: normal;%n");
out.format(" font-size: 10pt;%n");
out.format(" text-align: right;%n");
out.format(" table-layout: fixed;%n");
out.format(" word-wrap: break-word;%n");
out.format(" overflow-wrap: break-word;%n");
out.format("}%n");
out.format("%n");
out.format(".excelDefaults td {%n");
out.format(" padding: 1px 5px;%n");
out.format(" border: 1px solid silver;%n");
out.format("}%n");
out.format("%n");
out.format(".excelDefaults .colHeader {%n");
out.format(" background-color: silver;%n");
out.format(" font-weight: bold;%n");
out.format(" border: 1px solid black;%n");
out.format(" text-align: center;%n");
out.format(" padding: 1px 5px;%n");
out.format("}%n");
out.format("%n");
out.format(".excelDefaults .rowHeader {%n");
out.format(" background-color: silver;%n");
out.format(" font-weight: bold;%n");
out.format(" border: 1px solid black;%n");
out.format(" text-align: right;%n");
out.format(" padding: 1px 5px;%n");
out.format("}%n");
// now add css for each used style
Set<CellStyle> seen = new HashSet<>();
for (int i = 0; i < wb.getNumberOfSheets(); i++) {
Sheet sheet = wb.getSheetAt(i);
Iterator<Row> rows = sheet.rowIterator();
while (rows.hasNext()) {
Row row = rows.next();
for (Cell cell : row) {
CellStyle style = cell.getCellStyle();
if (!seen.contains(style)) {
printStyle(style);
seen.add(style);
}
}
}
}
}
private void printStyle(CellStyle style) {
out.format(".%s .%s {%n", DEFAULTS_CLASS, styleName(style));
styleContents(style);
out.format("}%n");
}
private void styleContents(CellStyle style) {
styleOut("text-align", style.getAlignment(), HALIGN);
styleOut("vertical-align", style.getVerticalAlignment(), VALIGN);
fontStyle(style);
borderStyles(style);
helper.colorStyles(style, out);
}
private void borderStyles(CellStyle style) {
styleOut("border-left", style.getBorderLeft(), BORDER);
styleOut("border-right", style.getBorderRight(), BORDER);
styleOut("border-top", style.getBorderTop(), BORDER);
styleOut("border-bottom", style.getBorderBottom(), BORDER);
}
private void fontStyle(CellStyle style) {
Font font = wb.getFontAt(style.getFontIndexAsInt());
if (font.getBold()) {
out.format(" font-weight: bold;%n");
}
if (font.getItalic()) {
out.format(" font-style: italic;%n");
}
int fontheight = font.getFontHeightInPoints();
if (fontheight == 9) {
//fix for stupid ol Windows
fontheight = 10;
}
out.format(" font-size: %dpt;%n", fontheight);
// Font color is handled with the other colors
}
private String styleName(CellStyle style) {
if (style == null) {
style = wb.getCellStyleAt((short) 0);
}
StringBuilder sb = new StringBuilder();
try (Formatter fmt = new Formatter(sb)) {
fmt.format("style_%02x", style.getIndex());
return fmt.toString();
}
}
private <K> void styleOut(String attr, K key, Map<K, String> mapping) {
String value = mapping.get(key);
if (value != null) {
out.format(" %s: %s;%n", attr, value);
}
}
private static CellType ultimateCellType(Cell c) {
CellType type = c.getCellType();
if (type == CellType.FORMULA) {
type = c.getCachedFormulaResultType();
}
return type;
}
private void printSheets() {
ensureOut();
Sheet sheet = wb.getSheetAt(0);
printSheet(sheet);
}
public void printSheet(Sheet sheet) {
ensureOut();
Map<Integer, Integer> widths = computeWidths(sheet);
int tableWidth = widths.get(IDX_TABLE_WIDTH);
out.format("<table class=%s style=\"width:%dpx;\">%n", DEFAULTS_CLASS, tableWidth);
printCols(widths);
printSheetContent(sheet);
out.format("</table>%n");
}
/**
* computes the column widths, defined by the sheet.
*
* @param sheet The sheet for which to compute widths
* @return Map with key: column index; value: column width in pixels
* <br>special keys:
* <br>{@link #IDX_HEADER_COL_WIDTH} - width of the header column
* <br>{@link #IDX_TABLE_WIDTH} - width of the entire table
*/
private Map<Integer, Integer> computeWidths(Sheet sheet) {
Map<Integer, Integer> ret = new TreeMap<>();
int tableWidth = 0;
ensureColumnBounds(sheet);
// compute width of the header column
int lastRowNum = sheet.getLastRowNum();
int headerCharCount = String.valueOf(lastRowNum).length();
int headerColWidth = widthToPixels((headerCharCount + 1) * 256.0);
ret.put(IDX_HEADER_COL_WIDTH, headerColWidth);
tableWidth += headerColWidth;
for (int i = firstColumn; i < endColumn; i++) {
int colWidth = widthToPixels(sheet.getColumnWidth(i));
ret.put(i, colWidth);
tableWidth += colWidth;
}
ret.put(IDX_TABLE_WIDTH, tableWidth);
return ret;
}
/**
* Probably platform-specific, but appears to be a close approximation on some systems
*
* @param widthUnits POI's native width unit (twips)
* @return the approximate number of pixels for a typical display
*/
protected int widthToPixels(final double widthUnits) {
return Math.toIntExact(Math.round(widthUnits * 9 / 256));
}
private void printCols(Map<Integer, Integer> widths) {
int headerColWidth = widths.get(IDX_HEADER_COL_WIDTH);
out.format("<col style=\"width:%dpx\"/>%n", headerColWidth);
for (int i = firstColumn; i < endColumn; i++) {
int colWidth = widths.get(i);
out.format("<col style=\"width:%dpx;\"/>%n", colWidth);
}
}
private void ensureColumnBounds(Sheet sheet) {
if (gotBounds) {
return;
}
Iterator<Row> iter = sheet.rowIterator();
firstColumn = (iter.hasNext() ? Integer.MAX_VALUE : 0);
endColumn = 0;
while (iter.hasNext()) {
Row row = iter.next();
short firstCell = row.getFirstCellNum();
if (firstCell >= 0) {
firstColumn = Math.min(firstColumn, firstCell);
endColumn = Math.max(endColumn, row.getLastCellNum());
}
}
gotBounds = true;
}
private void printColumnHeads() {
out.format("<thead>%n");
out.format(" <tr class=%s>%n", COL_HEAD_CLASS);
out.format(" <th class=%s>◊</th>%n", COL_HEAD_CLASS);
//noinspection UnusedDeclaration
StringBuilder colName = new StringBuilder();
for (int i = firstColumn; i < endColumn; i++) {
colName.setLength(0);
int cnum = i;
do {
colName.insert(0, (char) ('A' + cnum % 26));
cnum /= 26;
} while (cnum > 0);
out.format(" <th class=%s>%s</th>%n", COL_HEAD_CLASS, colName);
}
out.format(" </tr>%n");
out.format("</thead>%n");
}
private void printSheetContent(Sheet sheet) {
printColumnHeads();
out.format("<tbody>%n");
Iterator<Row> rows = sheet.rowIterator();
while (rows.hasNext()) {
Row row = rows.next();
out.format(" <tr>%n");
out.format(" <td class=%s>%d</td>%n", ROW_HEAD_CLASS,
row.getRowNum() + 1);
for (int i = firstColumn; i < endColumn; i++) {
String content = " ";
String attrs = "";
CellStyle style = null;
if (i >= row.getFirstCellNum() && i < row.getLastCellNum()) {
Cell cell = row.getCell(i);
if (cell != null) {
style = cell.getCellStyle();
attrs = tagStyle(cell, style);
//Set the value that is rendered for the cell
//also applies the format
CellFormat cf = CellFormat.getInstance(
style.getDataFormatString());
CellFormatResult result = cf.apply(cell);
content = result.text; //never null
if (content.isEmpty()) {
content = " ";
}
}
}
out.format(" <td class=%s %s>%s</td>%n", styleName(style),
attrs, content);
}
out.format(" </tr>%n");
}
out.format("</tbody>%n");
}
private String tagStyle(Cell cell, CellStyle style) {
if (style.getAlignment() == HorizontalAlignment.GENERAL) {
switch (ultimateCellType(cell)) {
case STRING:
return "style=\"text-align: left;\"";
case BOOLEAN:
case ERROR:
return "style=\"text-align: center;\"";
case NUMERIC:
default:
// "right" is the default
break;
}
}
return "";
}
}
HtmlHelper.java
package com.demo.exceltohtml;
import java.util.Formatter;
import org.apache.poi.ss.usermodel.CellStyle;
public interface HtmlHelper {
void colorStyles(CellStyle var1, Formatter var2);
}
HSSFHtmlHelper.java
package com.demo.exceltohtml;
import java.util.Formatter;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.hssf.util.HSSFColor.HSSFColorPredefined;
import org.apache.poi.ss.usermodel.CellStyle;
public class HSSFHtmlHelper implements HtmlHelper {
private final HSSFWorkbook wb;
private final HSSFPalette colors;
private static final HSSFColor HSSF_AUTO;
public HSSFHtmlHelper(HSSFWorkbook wb) {
this.wb = wb;
this.colors = wb.getCustomPalette();
}
public void colorStyles(CellStyle style, Formatter out) {
HSSFCellStyle cs = (HSSFCellStyle) style;
out.format(" /* fill pattern = %d */%n", cs.getFillPattern().getCode());
this.styleColor(out, "background-color", cs.getFillForegroundColor());
this.styleColor(out, "color", cs.getFont(this.wb).getColor());
this.styleColor(out, "border-left-color", cs.getLeftBorderColor());
this.styleColor(out, "border-right-color", cs.getRightBorderColor());
this.styleColor(out, "border-top-color", cs.getTopBorderColor());
this.styleColor(out, "border-bottom-color", cs.getBottomBorderColor());
}
private void styleColor(Formatter out, String attr, short index) {
HSSFColor color = this.colors.getColor(index);
if (index != HSSF_AUTO.getIndex() && color != null) {
short[] rgb = color.getTriplet();
out.format(" %s: #%02x%02x%02x; /* index = %d */%n", attr, rgb[0], rgb[1], rgb[2], index);
} else {
out.format(" /* %s: index = %d */%n", attr, index);
}
}
static {
HSSF_AUTO = HSSFColorPredefined.AUTOMATIC.getColor();
}
}
XSSFHtmlHelper.java
package com.demo.exceltohtml;
import java.util.Formatter;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
public class XSSFHtmlHelper implements HtmlHelper {
public XSSFHtmlHelper() {
}
public void colorStyles(CellStyle style, Formatter out) {
XSSFCellStyle cs = (XSSFCellStyle)style;
this.styleColor(out, "background-color", cs.getFillForegroundXSSFColor());
this.styleColor(out, "text-color", cs.getFont().getXSSFColor());
}
private void styleColor(Formatter out, String attr, XSSFColor color) {
if (color != null && !color.isAuto()) {
byte[] rgb = color.getRGB();
if (rgb != null) {
out.format(" %s: #%02x%02x%02x;%n", attr, rgb[0], rgb[1], rgb[2]);
byte[] argb = color.getARGB();
if (argb != null) {
out.format(" %s: rgba(0x%02x, 0x%02x, 0x%02x, 0x%02x);%n", attr, argb[3], argb[0], argb[1], argb[2]);
}
}
}
}
}