package org.apache.poi.ss.examples.html;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFFont;
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.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Formatter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import static org.apache.poi.ss.usermodel.CellStyle.*;
/**
* This example shows how to display a spreadsheet in HTML using the classes for
* spreadsheet display.
*
* @author Ken Arnold, Industrious Media LLC
*/
public class ToHtml {
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 ALIGN = mapFor(ALIGN_LEFT, "left",
ALIGN_CENTER, "center", ALIGN_RIGHT, "right", ALIGN_FILL, "left",
ALIGN_JUSTIFY, "left", ALIGN_CENTER_SELECTION, "center");
private static final Map VERTICAL_ALIGN = mapFor(
VERTICAL_BOTTOM, "bottom", VERTICAL_CENTER, "middle", VERTICAL_TOP,
"top");
private static final Map BORDER = mapFor(BORDER_DASH_DOT,
"dashed 1pt", BORDER_DASH_DOT_DOT, "dashed 1pt", BORDER_DASHED,
"dashed 1pt", BORDER_DOTTED, "dotted 1pt", BORDER_DOUBLE,
"double 3pt", BORDER_HAIR, "solid 1px", BORDER_MEDIUM, "solid 2pt",
BORDER_MEDIUM_DASH_DOT, "dashed 2pt", BORDER_MEDIUM_DASH_DOT_DOT,
"dashed 2pt", BORDER_MEDIUM_DASHED, "dashed 2pt", BORDER_NONE,
"none", BORDER_SLANTED_DASH_DOT, "dashed 2pt", BORDER_THICK,
"solid 3pt", BORDER_THIN, "dashed 1pt");
@SuppressWarnings({"unchecked"})
private static Map mapFor(Object... mapping) {
Map map = new HashMap();
for (int i = 0; i < mapping.length; i += 2) {
map.put((K) mapping[i], (V) mapping[i + 1]);
}
return map;
}
/**
* Creates a new converter to HTML for the given workbook.
*
* @param wb The workbook.
* @param output Where the HTML output will be written.
*
* @return An object for converting the workbook to HTML.
*/
public static ToHtml create(Workbook wb, Appendable output) {
return new ToHtml(wb, output);
}
/**
* Creates a new converter to HTML for the given workbook. If the path ends
* with ".xlsx" an {@link XSSFWorkbook} will be used; otherwise
* this will use an {@link HSSFWorkbook}.
*
* @param path The file that has the workbook.
* @param output Where the HTML output will be written.
*
* @return An object for converting the workbook to HTML.
*/
public static ToHtml create(String path, Appendable output)
throws IOException {
InputStream in = new FileInputStream(path);
if (path.endsWith(".xlsx"))
return createXSSF(in, output);
else
return createHSSF(in, output);
}
/**
* Creates a new converter to HTML for the given workbook. This attempts to
* detect whether the input is XML (so it should create an {@link
* XSSFWorkbook} or not (so it should create an {@link HSSFWorkbook}).
*
* @param in The input stream that has the workbook.
* @param output Where the HTML output will be written.
*
* @return An object for converting the workbook to HTML.
*
* @see #createHSSF(InputStream, Appendable)
* @see #createXSSF(InputStream, Appendable)
*/
public static ToHtml create(InputStream in, Appendable output)
throws IOException {
if (!in.markSupported())
throw new IllegalArgumentException("!in.markSupported()");
in.mark(1);
boolean isXml = (in.read() == '<');
in.reset();
if (isXml)
return createXSSF(in, output);
else
return createHSSF(in, output);
}
/**
* Creates a new converter to HTML for an {@link XSSFWorkbook}.
*
* @param in The input stream that has the workbook.
* @param output Where the HTML output will be written.
*
* @return An object for converting the workbook to HTML.
*/
public static ToHtml createXSSF(InputStream in, Appendable output)
throws IOException {
return create(new XSSFWorkbook(in), output);
}
/**
* Creates a new converter to HTML for an {@link HSSFWorkbook}.
*
* @param in The input stream that has the workbook.
* @param output Where the HTML output will be written.
*
* @return An object for converting the workbook to HTML.
*/
public static ToHtml createHSSF(InputStream in, Appendable output)
throws IOException {
return create(new HSSFWorkbook(in), output);
}
private ToHtml(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((XSSFWorkbook) wb);
else
throw new IllegalArgumentException(
"unknown workbook type: " + wb.getClass().getSimpleName());
}
/**
* Run this class as a program
*
* @param args The command line arguments.
*
* @throws Exception Exception we don't recover from.
*/
public static void main(String[] args) throws Exception {
ToHtml toHtml = create(args[0], System.out);
toHtml.setCompleteHTML(true);
toHtml.printStyles();
toHtml = create(args[0], new PrintWriter(new FileWriter(
"/tmp/k.html")));
toHtml.setCompleteHTML(true);
toHtml.printPage();
}
public void setCompleteHTML(boolean completeHTML) {
this.completeHTML = completeHTML;
}
public void printPage() throws IOException {
try {
ensureOut();
if (completeHTML) {
out.format(
"%n");
out.format("%n");
out.format("%n");
out.format("%n");
out.format("%n");
}
print();
if (completeHTML) {
out.format("%n");
out.format("%n");
}
} finally {
if (out != null)
out.close();
if (output instanceof Closeable) {
Closeable closeable = (Closeable) output;
closeable.close();
}
}
}
public void print() {
printInlineStyle();
printSheets();
}
private void printInlineStyle() {
//out.format("%n");
out.format("%n");
}
private void ensureOut() {
if (out == null)
out = new Formatter(output);
}
public void printStyles() {
ensureOut();
// First, copy the base css
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(
getClass().getResourceAsStream("excelStyle.css")));
String line;
while ((line = in.readLine()) != null) {
out.format("%s%n", line);
}
} catch (IOException e) {
throw new IllegalStateException("Reading standard css", e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
//noinspection ThrowFromFinallyBlock
throw new IllegalStateException("Reading standard css", e);
}
}
}
// now add css for each used style
Set seen = new HashSet();
for (int i = 0; i < wb.getNumberOfSheets(); i++) {
Sheet sheet = wb.getSheetAt(i);
Iterator 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(), ALIGN);
styleOut("vertical-align", style.getAlignment(), VERTICAL_ALIGN);
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.getFontIndex());
if (font.getBoldweight() >= HSSFFont.BOLDWEIGHT_NORMAL)
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();
Formatter fmt = new Formatter(sb);
fmt.format("style_%02x", style.getIndex());
return fmt.toString();
}
private void styleOut(String attr, K key, Map mapping) {
String value = mapping.get(key);
if (value != null) {
out.format(" %s: %s;%n", attr, value);
}
}
private static int ultimateCellType(Cell c) {
int type = c.getCellType();
if (type == Cell.CELL_TYPE_FORMULA)
type = c.getCachedFormulaResultType();
return type;
}
private void printSheets() {
ensureOut();
Sheet sheet = wb.getSheetAt(0);
printSheet(sheet);
}
public void printSheet(Sheet sheet) {
ensureOut();
out.format("