| @@ -4,7 +4,7 @@ | |||
| <parent> | |||
| <groupId>org.jeecgframework</groupId> | |||
| <artifactId>easypoi</artifactId> | |||
| <version>2.1.1-SNAPSHOT</version> | |||
| <version>2.1.2-SNAPSHOT</version> | |||
| </parent> | |||
| <artifactId>easypoi-annotation</artifactId> | |||
| <description>基础注解类,解耦合</description> | |||
| @@ -4,7 +4,7 @@ | |||
| <parent> | |||
| <groupId>org.jeecgframework</groupId> | |||
| <artifactId>easypoi</artifactId> | |||
| <version>2.1.1-SNAPSHOT</version> | |||
| <version>2.1.2-SNAPSHOT</version> | |||
| </parent> | |||
| <artifactId>easypoi-base</artifactId> | |||
| <dependencies> | |||
| @@ -0,0 +1,55 @@ | |||
| package org.jeecgframework.poi.excel; | |||
| import org.apache.poi.ss.usermodel.Workbook; | |||
| import org.jeecgframework.poi.excel.html.ExcelToHtmlServer; | |||
| /** | |||
| * Excel 变成界面 | |||
| * @author JueYue | |||
| * @date 2015年5月10日 上午11:51:48 | |||
| */ | |||
| public final class ExcelToHtmlUtil { | |||
| private ExcelToHtmlUtil() { | |||
| } | |||
| /** | |||
| * 转换成为Table | |||
| * @param wb Excel | |||
| * @return | |||
| */ | |||
| public static String toTableHtml(Workbook wb) { | |||
| return new ExcelToHtmlServer(wb, false, 0).printPage(); | |||
| } | |||
| /** | |||
| * 转换成为Table | |||
| * @param wb Excel | |||
| * @param sheetNum sheetNum | |||
| * @return | |||
| */ | |||
| public static String toTableHtml(Workbook wb, int sheetNum) { | |||
| return new ExcelToHtmlServer(wb, false, sheetNum).printPage(); | |||
| } | |||
| /** | |||
| * 转换成为完整界面 | |||
| * @param wb Excel | |||
| * @param sheetNum sheetNum | |||
| * @return | |||
| */ | |||
| public static String toAllHtml(Workbook wb) { | |||
| return new ExcelToHtmlServer(wb, true, 0).printPage(); | |||
| } | |||
| /** | |||
| * 转换成为完整界面 | |||
| * @param wb Excel | |||
| * @param sheetNum sheetNum | |||
| * @return | |||
| */ | |||
| public static String toAllHtml(Workbook wb, int sheetNum) { | |||
| return new ExcelToHtmlServer(wb, true, sheetNum).printPage(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,180 @@ | |||
| package org.jeecgframework.poi.excel.html; | |||
| import java.util.Formatter; | |||
| import java.util.Iterator; | |||
| import org.apache.poi.ss.usermodel.Cell; | |||
| import org.apache.poi.ss.usermodel.CellStyle; | |||
| import org.apache.poi.ss.usermodel.Row; | |||
| import org.apache.poi.ss.usermodel.Sheet; | |||
| import org.apache.poi.ss.usermodel.Workbook; | |||
| import org.jeecgframework.poi.excel.html.helper.CellValueHelper; | |||
| import org.jeecgframework.poi.excel.html.helper.MergedRegionHelper; | |||
| import org.jeecgframework.poi.excel.html.helper.StylerHelper; | |||
| /** | |||
| * Excel转换成Html 服务 | |||
| * @author JueYue | |||
| * @date 2015年5月10日 上午11:41:15 | |||
| */ | |||
| public class ExcelToHtmlServer { | |||
| private Workbook wb; | |||
| private int sheetNum; | |||
| private int cssRandom; | |||
| /*是不是完成界面*/ | |||
| private boolean completeHTML; | |||
| private Formatter out; | |||
| /*已经完成范围处理*/ | |||
| private boolean gotBounds; | |||
| private int firstColumn; | |||
| private int endColumn; | |||
| private static final String COL_HEAD_CLASS = "colHeader"; | |||
| private static final String ROW_HEAD_CLASS = "rowHeader"; | |||
| private static final String DEFAULTS_CLASS = "excelDefaults"; | |||
| public ExcelToHtmlServer(Workbook wb, boolean completeHTML, int sheetNum) { | |||
| this.wb = wb; | |||
| this.completeHTML = completeHTML; | |||
| this.sheetNum = sheetNum; | |||
| cssRandom = (int) Math.ceil(Math.random() * 1000); | |||
| } | |||
| public String printPage() { | |||
| try { | |||
| ensureOut(); | |||
| if (completeHTML) { | |||
| out.format("<!DOCTYPE HTML>%n"); | |||
| out.format("<html>%n"); | |||
| out.format("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">%n"); | |||
| out.format("<head>%n"); | |||
| } | |||
| new StylerHelper(wb, out, sheetNum, cssRandom); | |||
| if (completeHTML) { | |||
| out.format("</head>%n"); | |||
| out.format("<body>%n"); | |||
| } | |||
| print(); | |||
| if (completeHTML) { | |||
| out.format("</body>%n"); | |||
| out.format("</html>%n"); | |||
| } | |||
| return out.toString(); | |||
| } finally { | |||
| if (out != null) | |||
| out.close(); | |||
| } | |||
| } | |||
| private void print() { | |||
| printSheets(); | |||
| } | |||
| private void ensureOut() { | |||
| if (out == null) | |||
| out = new Formatter(new StringBuilder()); | |||
| } | |||
| private void printSheets() { | |||
| Sheet sheet = wb.getSheetAt(sheetNum); | |||
| printSheet(sheet); | |||
| } | |||
| private void printSheet(Sheet sheet) { | |||
| out.format("<table style='word-break:break-all' class=%s>%n", DEFAULTS_CLASS); | |||
| printCols(sheet); | |||
| printSheetContent(sheet); | |||
| out.format("</table>%n"); | |||
| } | |||
| private void printCols(Sheet sheet) { | |||
| out.format("<col/>%n"); | |||
| ensureColumnBounds(sheet); | |||
| for (int i = firstColumn; i < endColumn; i++) { | |||
| out.format("<col style='width:%spx;' />%n", sheet.getColumnWidth(i) / 32); | |||
| } | |||
| } | |||
| 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(Sheet sheet) { | |||
| out.format("<thead>%n"); | |||
| out.format(" <tr class=%s>%n", COL_HEAD_CLASS); | |||
| out.format(" <th class=%s>◊</th>%n", COL_HEAD_CLASS); | |||
| 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(sheet); | |||
| MergedRegionHelper mergedRegionHelper = new MergedRegionHelper(sheet); | |||
| CellValueHelper cellValueHelper = new CellValueHelper(wb, cssRandom); | |||
| out.format("<tbody>%n"); | |||
| Iterator<Row> rows = sheet.rowIterator(); | |||
| int rowIndex = 1; | |||
| while (rows.hasNext()) { | |||
| Row row = rows.next(); | |||
| out.format(" <tr style='height:%spx;'>%n", row.getHeight() / 15); | |||
| out.format(" <td class='%s'>%d</td>%n", ROW_HEAD_CLASS, row.getRowNum() + 1); | |||
| for (int i = firstColumn; i < endColumn; i++) { | |||
| if (mergedRegionHelper.isNeedCreate(rowIndex, i)) { | |||
| String content = " "; | |||
| CellStyle style = null; | |||
| if (i >= row.getFirstCellNum() && i < row.getLastCellNum()) { | |||
| Cell cell = row.getCell(i); | |||
| if (cell != null) { | |||
| style = cell.getCellStyle(); | |||
| content = cellValueHelper.getHtmlValue(cell); | |||
| } | |||
| } | |||
| if (mergedRegionHelper.isMergedRegion(rowIndex, i)) { | |||
| Integer[] rowAndColSpan = mergedRegionHelper.getRowAndColSpan(rowIndex, i); | |||
| out.format(" <td rowspan='%s' colspan='%s' class='%s' >%s</td>%n", | |||
| rowAndColSpan[0], rowAndColSpan[1], styleName(style), content); | |||
| } else { | |||
| out.format(" <td class='%s'>%s</td>%n", styleName(style), content); | |||
| } | |||
| } | |||
| } | |||
| out.format(" </tr>%n"); | |||
| rowIndex++; | |||
| } | |||
| out.format("</tbody>%n"); | |||
| } | |||
| private String styleName(CellStyle style) { | |||
| if (style == null) | |||
| return ""; | |||
| return String.format("style_%02x_%s font_%s_%s", style.getIndex(), cssRandom, | |||
| style.getFontIndex(), cssRandom); | |||
| } | |||
| } | |||
| @@ -0,0 +1,140 @@ | |||
| package org.jeecgframework.poi.excel.html.helper; | |||
| import java.util.HashMap; | |||
| import java.util.Map; | |||
| import org.apache.poi.hssf.usermodel.HSSFRichTextString; | |||
| import org.apache.poi.hssf.usermodel.HSSFWorkbook; | |||
| import org.apache.poi.ss.usermodel.Cell; | |||
| import org.apache.poi.ss.usermodel.Font; | |||
| import org.apache.poi.ss.usermodel.Workbook; | |||
| import org.apache.poi.xssf.usermodel.XSSFFont; | |||
| import org.apache.poi.xssf.usermodel.XSSFRichTextString; | |||
| import org.apache.poi.xssf.usermodel.XSSFWorkbook; | |||
| import com.google.common.xml.XmlEscapers; | |||
| /** | |||
| * Cell值帮助类 | |||
| * @author JueYue | |||
| * @date 2015年5月9日 下午10:31:32 | |||
| */ | |||
| public class CellValueHelper { | |||
| /** | |||
| * Excel 格式 | |||
| */ | |||
| private boolean is07; | |||
| private int cssRandom; | |||
| private Map<String, String> fontCache = new HashMap<String, String>(); | |||
| public CellValueHelper(Workbook wb, int cssRandom) { | |||
| this.cssRandom = cssRandom; | |||
| if (wb instanceof HSSFWorkbook) | |||
| is07 = false; | |||
| else if (wb instanceof XSSFWorkbook) { | |||
| is07 = true; | |||
| cacheFontInfo(wb); | |||
| } else | |||
| throw new IllegalArgumentException("unknown workbook type: " | |||
| + wb.getClass().getSimpleName()); | |||
| } | |||
| /** | |||
| * O7 版本坑爹bug | |||
| * @param wb | |||
| */ | |||
| private void cacheFontInfo(Workbook wb) { | |||
| for (short i = 0, le = wb.getNumberOfFonts(); i < le; i++) { | |||
| Font font = wb.getFontAt(i); | |||
| fontCache.put(font.getBoldweight() + "_" + font.getItalic() + "_" + font.getFontName() | |||
| + "_" + font.getFontHeightInPoints() + "_" + font.getColor(), | |||
| font.getIndex() + ""); | |||
| } | |||
| } | |||
| public String getHtmlValue(Cell cell) { | |||
| if (Cell.CELL_TYPE_BOOLEAN == cell.getCellType() | |||
| || Cell.CELL_TYPE_NUMERIC == cell.getCellType()) { | |||
| cell.setCellType(Cell.CELL_TYPE_STRING); | |||
| return cell.getStringCellValue(); | |||
| } else if (Cell.CELL_TYPE_STRING == cell.getCellType()) { | |||
| if (cell.getRichStringCellValue().numFormattingRuns() == 0) { | |||
| return XmlEscapers.xmlContentEscaper().escape(cell.getStringCellValue()); | |||
| } else if (is07) { | |||
| return getXSSFRichString((XSSFRichTextString) cell.getRichStringCellValue()); | |||
| } else { | |||
| return getHSSFRichString((HSSFRichTextString) cell.getRichStringCellValue()); | |||
| } | |||
| } | |||
| return ""; | |||
| } | |||
| /** | |||
| * 03版本复杂数据 | |||
| * @param rich | |||
| * @return | |||
| */ | |||
| private String getHSSFRichString(HSSFRichTextString rich) { | |||
| int nums = rich.numFormattingRuns(); | |||
| StringBuilder sb = new StringBuilder(); | |||
| String text = rich.toString(); | |||
| int currentIndex = 0; | |||
| sb.append(text.substring(0, rich.getIndexOfFormattingRun(0))); | |||
| for (int i = 0; i < nums; i++) { | |||
| sb.append("<span "); | |||
| sb.append("class='font_" + rich.getFontOfFormattingRun(i)); | |||
| sb.append("_"); | |||
| sb.append(cssRandom); | |||
| sb.append("'>"); | |||
| currentIndex = rich.getIndexOfFormattingRun(i); | |||
| if (i < nums - 1) { | |||
| sb.append(XmlEscapers.xmlContentEscaper().escape( | |||
| text.substring(currentIndex, rich.getIndexOfFormattingRun(i + 1)))); | |||
| } else { | |||
| sb.append(XmlEscapers.xmlContentEscaper().escape( | |||
| text.substring(currentIndex, text.length()))); | |||
| } | |||
| sb.append("</span>"); | |||
| } | |||
| return sb.toString(); | |||
| } | |||
| /** | |||
| * 07版本复杂数据 | |||
| * @param rich | |||
| * @return | |||
| */ | |||
| private String getXSSFRichString(XSSFRichTextString rich) { | |||
| int nums = rich.numFormattingRuns(); | |||
| StringBuilder sb = new StringBuilder(); | |||
| String text = rich.toString(); | |||
| int currentIndex = 0, lastIndex = 0; | |||
| for (int i = 1; i <= nums; i++) { | |||
| sb.append("<span "); | |||
| try { | |||
| sb.append("class='font_" + getFontIndex(rich.getFontOfFormattingRun(i - 1))); | |||
| sb.append("_"); | |||
| sb.append(cssRandom); | |||
| sb.append("'"); | |||
| } catch (Exception e) { | |||
| } | |||
| sb.append(">"); | |||
| currentIndex = rich.getIndexOfFormattingRun(i) == -1 ? text.length() : rich | |||
| .getIndexOfFormattingRun(i); | |||
| sb.append(XmlEscapers.xmlContentEscaper().escape( | |||
| text.substring(lastIndex, currentIndex))); | |||
| sb.append("</span>"); | |||
| lastIndex = currentIndex; | |||
| } | |||
| return sb.toString(); | |||
| } | |||
| private String getFontIndex(XSSFFont font) { | |||
| return fontCache.get(font.getBoldweight() + "_" + font.getItalic() + "_" | |||
| + font.getFontName() + "_" + font.getFontHeightInPoints() + "_" | |||
| + font.getColor()); | |||
| } | |||
| } | |||
| @@ -0,0 +1,81 @@ | |||
| package org.jeecgframework.poi.excel.html.helper; | |||
| import java.util.HashMap; | |||
| import java.util.HashSet; | |||
| import java.util.Map; | |||
| import java.util.Set; | |||
| import org.apache.poi.ss.usermodel.Sheet; | |||
| /** | |||
| * 合并单元格帮助类 | |||
| * @author JueYue | |||
| * @date 2015年5月9日 下午2:13:35 | |||
| */ | |||
| public class MergedRegionHelper { | |||
| private Map<String, Integer[]> mergedCache = new HashMap<String, Integer[]>(); | |||
| private Set<String> notNeedCread = new HashSet<String>(); | |||
| public MergedRegionHelper(Sheet sheet) { | |||
| getAllMergedRegion(sheet); | |||
| } | |||
| private void getAllMergedRegion(Sheet sheet) { | |||
| int nums = sheet.getNumMergedRegions(); | |||
| for (int i = 0; i < nums; i++) { | |||
| handerMergedString(sheet.getMergedRegion(i).formatAsString()); | |||
| } | |||
| } | |||
| /** | |||
| * 根据合并输出内容,处理合并单元格事情 | |||
| * @param formatAsString | |||
| */ | |||
| private void handerMergedString(String formatAsString) { | |||
| String[] strArr = formatAsString.split(":"); | |||
| int startCol = strArr[0].charAt(0) - 65; | |||
| int startRol = Integer.valueOf(strArr[0].substring(1)); | |||
| int endCol = strArr[1].charAt(0) - 65; | |||
| int endRol = Integer.valueOf(strArr[1].substring(1)); | |||
| mergedCache.put(startRol + "_" + startCol, new Integer[] { endRol - startRol + 1, | |||
| endCol - startCol + 1 }); | |||
| for (int i = startRol; i <= endRol; i++) { | |||
| for (int j = startCol; j <= endCol; j++) { | |||
| notNeedCread.add(i + "_" + j); | |||
| } | |||
| } | |||
| notNeedCread.remove(startRol + "_" + startCol); | |||
| } | |||
| /** | |||
| * 是不是需要创建这个TD | |||
| * @param row | |||
| * @param col | |||
| * @return | |||
| */ | |||
| public boolean isNeedCreate(int row, int col) { | |||
| return !notNeedCread.contains(row + "_" + col); | |||
| } | |||
| /** | |||
| * 是不是合并区域 | |||
| * @param row | |||
| * @param col | |||
| * @return | |||
| */ | |||
| public boolean isMergedRegion(int row, int col) { | |||
| return mergedCache.containsKey(row + "_" + col); | |||
| } | |||
| /** | |||
| * 获取合并区域 | |||
| * @param row | |||
| * @param col | |||
| * @return | |||
| */ | |||
| public Integer[] getRowAndColSpan(int row, int col) { | |||
| return mergedCache.get(row + "_" + col); | |||
| } | |||
| } | |||
| @@ -0,0 +1,278 @@ | |||
| package org.jeecgframework.poi.excel.html.helper; | |||
| import static org.apache.poi.ss.usermodel.CellStyle.ALIGN_CENTER; | |||
| import static org.apache.poi.ss.usermodel.CellStyle.ALIGN_CENTER_SELECTION; | |||
| import static org.apache.poi.ss.usermodel.CellStyle.ALIGN_FILL; | |||
| import static org.apache.poi.ss.usermodel.CellStyle.ALIGN_JUSTIFY; | |||
| import static org.apache.poi.ss.usermodel.CellStyle.ALIGN_LEFT; | |||
| import static org.apache.poi.ss.usermodel.CellStyle.ALIGN_RIGHT; | |||
| import static org.apache.poi.ss.usermodel.CellStyle.VERTICAL_BOTTOM; | |||
| import static org.apache.poi.ss.usermodel.CellStyle.VERTICAL_CENTER; | |||
| import static org.apache.poi.ss.usermodel.CellStyle.VERTICAL_TOP; | |||
| import java.io.BufferedReader; | |||
| import java.io.IOException; | |||
| import java.io.InputStreamReader; | |||
| import java.util.Formatter; | |||
| import java.util.HashSet; | |||
| import java.util.Iterator; | |||
| import java.util.Map; | |||
| import java.util.Set; | |||
| 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.ss.usermodel.Cell; | |||
| import org.apache.poi.ss.usermodel.CellStyle; | |||
| import org.apache.poi.ss.usermodel.Color; | |||
| 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.XSSFCellStyle; | |||
| import org.apache.poi.xssf.usermodel.XSSFColor; | |||
| import org.apache.poi.xssf.usermodel.XSSFFont; | |||
| import org.apache.poi.xssf.usermodel.XSSFWorkbook; | |||
| import org.jeecgframework.poi.util.PoiPublicUtil; | |||
| /** | |||
| * 样式帮助类 | |||
| * @author JueYue | |||
| * @date 2015年5月9日 下午4:04:24 | |||
| */ | |||
| public class StylerHelper { | |||
| private static String DEFAULTS_CLASS_CSS; | |||
| private static final String DEFAULTS_CLASS = "excelDefaults"; | |||
| private static final Map<Short, String> ALIGN = PoiPublicUtil.mapFor(ALIGN_LEFT, | |||
| "left", ALIGN_CENTER, "center", | |||
| ALIGN_RIGHT, "right", ALIGN_FILL, | |||
| "left", ALIGN_JUSTIFY, "left", | |||
| ALIGN_CENTER_SELECTION, "center"); | |||
| private static final Map<Short, String> VERTICAL_ALIGN = PoiPublicUtil.mapFor(VERTICAL_BOTTOM, | |||
| "bottom", VERTICAL_CENTER, "middle", | |||
| VERTICAL_TOP, "top"); | |||
| private Formatter out; | |||
| private Sheet sheet; | |||
| private HtmlHelper helper; | |||
| private int sheetNum; | |||
| private int cssRandom; | |||
| public StylerHelper(Workbook wb, Formatter out, int sheetNum, int cssRandom) { | |||
| this.out = out; | |||
| this.sheetNum = sheetNum; | |||
| this.cssRandom = cssRandom; | |||
| 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()); | |||
| printInlineStyle(wb); | |||
| } | |||
| private void printInlineStyle(Workbook wb) { | |||
| out.format("<style type=\"text/css\">%n"); | |||
| printStyles(wb); | |||
| prontFonts(wb); | |||
| out.format("</style>%n"); | |||
| } | |||
| private void prontFonts(Workbook wb) { | |||
| for (short i = 0, le = wb.getNumberOfFonts(); i < le; i++) { | |||
| Font font = wb.getFontAt(i); | |||
| out.format(".%s .%s {%n", DEFAULTS_CLASS, "font_" + i + "_" + cssRandom); | |||
| fontStyle(font); | |||
| out.format("}%n"); | |||
| } | |||
| } | |||
| public void printStyles(Workbook wb) { | |||
| if (DEFAULTS_CLASS_CSS == null) { | |||
| DEFAULTS_CLASS_CSS = getDefaultsClassCss(); | |||
| } | |||
| out.format(DEFAULTS_CLASS_CSS); | |||
| Set<CellStyle> seen = new HashSet<CellStyle>(); | |||
| sheet = wb.getSheetAt(sheetNum); | |||
| 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); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @SuppressWarnings("resource") | |||
| private String getDefaultsClassCss() { | |||
| BufferedReader in = null; | |||
| StringBuilder sb = new StringBuilder(); | |||
| Formatter formatter = new Formatter(sb); | |||
| try { | |||
| in = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream( | |||
| "excelStyle.css"))); | |||
| String line; | |||
| while ((line = in.readLine()) != null) { | |||
| formatter.format("%s%n", line); | |||
| } | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException("Reading standard css", e); | |||
| } finally { | |||
| if (in != null) { | |||
| try { | |||
| in.close(); | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException("Reading standard css", e); | |||
| } | |||
| } | |||
| } | |||
| return formatter.toString(); | |||
| } | |||
| private void printStyle(CellStyle style) { | |||
| out.format(".%s .%s {%n", DEFAULTS_CLASS, styleName(style)); | |||
| styleContents(style); | |||
| out.format("}%n"); | |||
| } | |||
| private void styleContents(CellStyle style) { | |||
| if (style.getAlignment() != 2) { | |||
| styleOut("text-align", style.getAlignment(), ALIGN); | |||
| styleOut("vertical-align", style.getAlignment(), VERTICAL_ALIGN); | |||
| } | |||
| helper.colorStyles(style, out); | |||
| } | |||
| private void fontStyle(Font font) { | |||
| if (font.getBoldweight() >= Font.BOLDWEIGHT_BOLD) | |||
| out.format(" font-weight: bold;%n"); | |||
| if (font.getItalic()) | |||
| out.format(" font-style: italic;%n"); | |||
| out.format(" font-family: %s;%n", font.getFontName()); | |||
| int fontheight = font.getFontHeightInPoints(); | |||
| if (fontheight == 9) { | |||
| fontheight = 10; | |||
| } | |||
| out.format(" font-size: %dpt;%n", fontheight); | |||
| helper.styleColor(out, "color", getColor(font)); | |||
| } | |||
| private Color getColor(Font font) { | |||
| if (helper instanceof HSSFHtmlHelper) { | |||
| return ((HSSFWorkbook) sheet.getWorkbook()).getCustomPalette() | |||
| .getColor(font.getColor()); | |||
| } else { | |||
| return ((XSSFFont) font).getXSSFColor(); | |||
| } | |||
| } | |||
| private String styleName(CellStyle style) { | |||
| if (style == null) | |||
| return ""; | |||
| return String.format("style_%02x_%s", style.getIndex(), cssRandom); | |||
| } | |||
| 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 interface HtmlHelper { | |||
| /** | |||
| * Outputs the appropriate CSS style for the given cell style. | |||
| * | |||
| * @param style The cell style. | |||
| * @param out The place to write the output. | |||
| */ | |||
| void colorStyles(CellStyle style, Formatter out); | |||
| void styleColor(Formatter out, String attr, Color color); | |||
| } | |||
| private class HSSFHtmlHelper implements HtmlHelper { | |||
| private final HSSFWorkbook wb; | |||
| private final HSSFPalette colors; | |||
| private HSSFColor HSSF_AUTO = new HSSFColor.AUTOMATIC(); | |||
| public HSSFHtmlHelper(HSSFWorkbook wb) { | |||
| this.wb = wb; | |||
| colors = wb.getCustomPalette(); | |||
| } | |||
| public void colorStyles(CellStyle style, Formatter out) { | |||
| HSSFCellStyle cs = (HSSFCellStyle) style; | |||
| out.format(" /* fill pattern = %d */%n", cs.getFillPattern()); | |||
| styleColor(out, "background-color", cs.getFillForegroundColor()); | |||
| styleColor(out, "color", colors.getColor(cs.getFont(wb).getColor())); | |||
| } | |||
| private void styleColor(Formatter out, String attr, short index) { | |||
| HSSFColor color = colors.getColor(index); | |||
| if (index == HSSF_AUTO.getIndex() || color == null) { | |||
| out.format(" /* %s: index = %d */%n", attr, index); | |||
| } else { | |||
| short[] rgb = color.getTriplet(); | |||
| out.format(" %s: #%02x%02x%02x; /* index = %d */%n", attr, rgb[0], rgb[1], rgb[2], | |||
| index); | |||
| } | |||
| } | |||
| public void styleColor(Formatter out, String attr, Color color) { | |||
| if (color == null) { | |||
| return; | |||
| } | |||
| HSSFColor hSSFColor = (HSSFColor) color; | |||
| short[] rgb = hSSFColor.getTriplet(); | |||
| out.format(" %s: #%02x%02x%02x; %n", attr, rgb[0], rgb[1], rgb[2]); | |||
| } | |||
| } | |||
| /** | |||
| * Implementation of {@link HtmlHelper} for XSSF files. | |||
| * | |||
| * @author Ken Arnold, Industrious Media LLC | |||
| */ | |||
| private class XSSFHtmlHelper implements HtmlHelper { | |||
| public XSSFHtmlHelper(XSSFWorkbook wb) { | |||
| } | |||
| public void colorStyles(CellStyle style, Formatter out) { | |||
| XSSFCellStyle cs = (XSSFCellStyle) style; | |||
| styleColor(out, "background-color", cs.getFillForegroundXSSFColor()); | |||
| styleColor(out, "color", cs.getFont().getXSSFColor()); | |||
| } | |||
| public void styleColor(Formatter out, String attr, Color color) { | |||
| XSSFColor xSSFColor = (XSSFColor) color; | |||
| if (color == null || xSSFColor.isAuto()) | |||
| return; | |||
| byte[] rgb = xSSFColor.getRgb(); | |||
| if (rgb == null) { | |||
| return; | |||
| } | |||
| out.format(" %s: #%02x%02x%02x;%n", attr, rgb[0], rgb[1], rgb[2]); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,45 @@ | |||
| .excelDefaults { | |||
| background-color: white; | |||
| color: black; | |||
| text-decoration: none; | |||
| direction: ltr; | |||
| text-transform: none; | |||
| text-indent: 0; | |||
| letter-spacing: 0; | |||
| word-spacing: 0; | |||
| white-space: normal; | |||
| unicode-bidi: normal; | |||
| vertical-align: 0; | |||
| text-shadow: none; | |||
| padding: 0; | |||
| margin: 0; | |||
| border-collapse: collapse; | |||
| white-space: pre-wrap; | |||
| word-wrap: break-word; | |||
| word-break: break-all; | |||
| } | |||
| .excelDefaults td { | |||
| padding: 1px 5px; | |||
| border: 1px solid silver; | |||
| border-color: #000000; | |||
| text-align: center; | |||
| vertical-align: middle; | |||
| font-size: 12pt; | |||
| } | |||
| .excelDefaults .colHeader { | |||
| background-color: silver; | |||
| font-weight: bold; | |||
| border: 1px solid black; | |||
| text-align: center; | |||
| padding: 1px 5px; | |||
| } | |||
| .excelDefaults .rowHeader { | |||
| background-color: silver; | |||
| font-weight: bold; | |||
| border: 1px solid black; | |||
| text-align: right; | |||
| padding: 1px 5px; | |||
| } | |||
| @@ -68,6 +68,15 @@ public final class PoiPublicUtil { | |||
| } | |||
| @SuppressWarnings({ "unchecked" }) | |||
| public static <K, V> Map<K, V> mapFor(Object... mapping) { | |||
| Map<K, V> map = new HashMap<K, V>(); | |||
| for (int i = 0; i < mapping.length; i += 2) { | |||
| map.put((K) mapping[i], (V) mapping[i + 1]); | |||
| } | |||
| return map; | |||
| } | |||
| /** | |||
| * 彻底创建一个对象 | |||
| * | |||
| @@ -4,7 +4,7 @@ | |||
| <parent> | |||
| <groupId>org.jeecgframework</groupId> | |||
| <artifactId>easypoi</artifactId> | |||
| <version>2.1.1-SNAPSHOT</version> | |||
| <version>2.1.2-SNAPSHOT</version> | |||
| </parent> | |||
| <artifactId>easypoi-test</artifactId> | |||
| <dependencies> | |||
| @@ -4,7 +4,7 @@ | |||
| <parent> | |||
| <groupId>org.jeecgframework</groupId> | |||
| <artifactId>easypoi</artifactId> | |||
| <version>2.1.1-SNAPSHOT</version> | |||
| <version>2.1.2-SNAPSHOT</version> | |||
| </parent> | |||
| <artifactId>easypoi-web</artifactId> | |||
| <dependencies> | |||
| @@ -0,0 +1,54 @@ | |||
| package org.jeecgframework.poi.excel.html.convert; | |||
| import java.util.Iterator; | |||
| import org.apache.poi.ss.usermodel.Cell; | |||
| import org.apache.poi.ss.usermodel.Row; | |||
| import org.apache.poi.ss.usermodel.Sheet; | |||
| import org.apache.poi.ss.usermodel.Workbook; | |||
| /** | |||
| * Excel 转换成为Html | |||
| * @author JueYue | |||
| * @date 2015年5月7日 下午10:06:51 | |||
| */ | |||
| public final class ExcelConverHtmlUtil { | |||
| private static final String STARTHTML = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\"><html><head>"; | |||
| private static final String HTML_TR_S = "<tr>"; | |||
| private static final String HTML_TR_E = "</tr>"; | |||
| private static final String HTML_TD_S = "<td>"; | |||
| private static final String HTML_TD_E = "</td>"; | |||
| private ExcelConverHtmlUtil() { | |||
| } | |||
| public String convert(Workbook workbook, int... sheets) { | |||
| StringBuilder html = new StringBuilder(STARTHTML); | |||
| StringBuilder css = new StringBuilder(); | |||
| StringBuilder body = new StringBuilder(); | |||
| sheetConverToHtml(workbook.getSheetAt(sheets[0]), css, body); | |||
| html.append(css); | |||
| html.append(body); | |||
| return html.toString(); | |||
| } | |||
| private void sheetConverToHtml(Sheet sheet, StringBuilder css, StringBuilder body) { | |||
| Iterator<Row> rows = sheet.rowIterator(); | |||
| Iterator<Cell> cells = null; | |||
| while (rows.hasNext()) { | |||
| Row row = rows.next(); | |||
| cells = row.cellIterator(); | |||
| body.append(HTML_TR_S); | |||
| while (cells.hasNext()) { | |||
| Cell cell = cells.next(); | |||
| body.append(HTML_TD_S); | |||
| body.append(cell.toString()); | |||
| body.append(HTML_TD_E); | |||
| } | |||
| body.append(HTML_TR_E); | |||
| } | |||
| } | |||
| } | |||
| @@ -3,7 +3,7 @@ | |||
| <modelVersion>4.0.0</modelVersion> | |||
| <groupId>org.jeecgframework</groupId> | |||
| <artifactId>easypoi</artifactId> | |||
| <version>2.1.1-SNAPSHOT</version> | |||
| <version>2.1.2-SNAPSHOT</version> | |||
| <packaging>pom</packaging> | |||
| <name>easypoi</name> | |||
| <modules> | |||
| @@ -24,7 +24,7 @@ | |||
| </developers> | |||
| <properties> | |||
| <sub.version>2.1.1-SNAPSHOT</sub.version> | |||
| <sub.version>2.1.2-SNAPSHOT</sub.version> | |||
| <poi.version>3.9</poi.version> | |||
| <xerces.version>2.9.1</xerces.version> | |||
| <guava.version>16.0.1</guava.version> | |||