@@ -10,8 +10,14 @@ | |||
<arguments> | |||
</arguments> | |||
</buildCommand> | |||
<buildCommand> | |||
<name>org.eclipse.m2e.core.maven2Builder</name> | |||
<arguments> | |||
</arguments> | |||
</buildCommand> | |||
</buildSpec> | |||
<natures> | |||
<nature>org.eclipse.m2e.core.maven2Nature</nature> | |||
<nature>org.springsource.ide.eclipse.gradle.core.nature</nature> | |||
<nature>org.eclipse.jdt.core.javanature</nature> | |||
</natures> | |||
@@ -1,13 +1,12 @@ | |||
# | |||
#Thu May 26 14:01:50 CST 2016 | |||
org.eclipse.jdt.core.compiler.debug.localVariable=generate | |||
org.eclipse.jdt.core.compiler.compliance=1.7 | |||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve | |||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate | |||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 | |||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error | |||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate | |||
eclipse.preferences.version=1 | |||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled | |||
org.eclipse.jdt.core.compiler.source=1.7 | |||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 | |||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve | |||
org.eclipse.jdt.core.compiler.compliance=1.6 | |||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate | |||
org.eclipse.jdt.core.compiler.debug.localVariable=generate | |||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate | |||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error | |||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error | |||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning | |||
org.eclipse.jdt.core.compiler.source=1.6 |
@@ -52,6 +52,13 @@ | |||
<optional>true</optional> | |||
</dependency> | |||
<!-- 处理Excel --> | |||
<dependency> | |||
<groupId>org.jsoup</groupId> | |||
<artifactId>jsoup</artifactId> | |||
<optional>true</optional> | |||
</dependency> | |||
<!-- google 工具类 --> | |||
<dependency> | |||
<groupId>com.google.guava</groupId> | |||
@@ -0,0 +1,255 @@ | |||
package org.jeecgframework.poi.excel.html; | |||
import java.util.Map; | |||
import java.util.List; | |||
import org.jsoup.Jsoup; | |||
import org.slf4j.Logger; | |||
import java.util.HashMap; | |||
import java.util.LinkedList; | |||
import org.slf4j.LoggerFactory; | |||
import org.jsoup.nodes.Element; | |||
import org.jsoup.select.Elements; | |||
import javax.management.RuntimeErrorException; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.apache.poi.ss.usermodel.Cell; | |||
import org.apache.poi.ss.usermodel.Sheet; | |||
import org.apache.poi.ss.usermodel.Workbook; | |||
import org.apache.poi.ss.usermodel.CellStyle; | |||
import org.apache.poi.ss.usermodel.Row; | |||
import org.apache.poi.ss.util.CellRangeAddress; | |||
import org.jeecgframework.poi.excel.export.styler.ExcelExportStylerDefaultImpl; | |||
import org.jeecgframework.poi.excel.html.css.CssParseServer; | |||
import org.jeecgframework.poi.excel.html.css.ICssConvertToExcel; | |||
import org.jeecgframework.poi.excel.html.css.impl.AlignCssConvertImpl; | |||
import org.jeecgframework.poi.excel.html.css.impl.BackgroundCssConvertImpl; | |||
import org.jeecgframework.poi.excel.html.css.impl.BorderCssConverImpl; | |||
import org.jeecgframework.poi.excel.html.css.impl.HeightCssConverImpl; | |||
import org.jeecgframework.poi.excel.html.css.impl.TextCssConvertImpl; | |||
import org.jeecgframework.poi.excel.html.css.impl.WidthCssConverImpl; | |||
import org.jeecgframework.poi.excel.html.entity.CellStyleEntity; | |||
import org.jeecgframework.poi.excel.html.entity.HtmlCssConstant; | |||
/** | |||
* 读取Table数据生成Excel | |||
* @author JueYue | |||
* 2017年3月19日 | |||
*/ | |||
public class HtmlToExcelServer { | |||
private final Logger LOGGER = LoggerFactory | |||
.getLogger(HtmlToExcelServer.class); | |||
//样式 | |||
private final List<ICssConvertToExcel> STYLE_APPLIERS = new LinkedList<ICssConvertToExcel>(); | |||
{ | |||
STYLE_APPLIERS.add(new AlignCssConvertImpl()); | |||
STYLE_APPLIERS.add(new BackgroundCssConvertImpl()); | |||
STYLE_APPLIERS.add(new BorderCssConverImpl()); | |||
STYLE_APPLIERS.add(new TextCssConvertImpl()); | |||
} | |||
//Cell 高宽 | |||
private final List<ICssConvertToExcel> SHEET_APPLIERS = new LinkedList<ICssConvertToExcel>(); | |||
{ | |||
SHEET_APPLIERS.add(new WidthCssConverImpl()); | |||
SHEET_APPLIERS.add(new HeightCssConverImpl()); | |||
} | |||
private Sheet sheet; | |||
private Map<String, Object> cellsOccupied = new HashMap<String, Object>(); | |||
private Map<String, CellStyle> cellStyles = new HashMap<String, CellStyle>(); | |||
private CellStyle defaultCellStyle; | |||
private int maxRow = 0; | |||
private CssParseServer cssParse = new CssParseServer(); | |||
// -- | |||
// private methods | |||
private void processTable(Element table) { | |||
int rowIndex = 0; | |||
if (maxRow > 0) { | |||
// blank row | |||
maxRow += 2; | |||
rowIndex = maxRow; | |||
} | |||
LOGGER.debug("Interate Table Rows."); | |||
for (Element row : table.select("tr")) { | |||
LOGGER.debug("Parse Table Row [{}]. Row Index [{}].", row, rowIndex); | |||
int colIndex = 0; | |||
LOGGER.debug("Interate Cols."); | |||
for (Element td : row.select("td, th")) { | |||
// skip occupied cell | |||
while (cellsOccupied.get(rowIndex + "_" + colIndex) != null) { | |||
LOGGER.debug("Cell [{}][{}] Has Been Occupied, Skip.", rowIndex, colIndex); | |||
++colIndex; | |||
} | |||
LOGGER.debug("Parse Col [{}], Col Index [{}].", td, colIndex); | |||
int rowSpan = 0; | |||
String strRowSpan = td.attr("rowspan"); | |||
if (StringUtils.isNotBlank(strRowSpan) && StringUtils.isNumeric(strRowSpan)) { | |||
LOGGER.debug("Found Row Span [{}].", strRowSpan); | |||
rowSpan = Integer.parseInt(strRowSpan); | |||
} | |||
int colSpan = 0; | |||
String strColSpan = td.attr("colspan"); | |||
if (StringUtils.isNotBlank(strColSpan) && StringUtils.isNumeric(strColSpan)) { | |||
LOGGER.debug("Found Col Span [{}].", strColSpan); | |||
colSpan = Integer.parseInt(strColSpan); | |||
} | |||
// col span & row span | |||
if (colSpan > 1 && rowSpan > 1) { | |||
spanRowAndCol(td, rowIndex, colIndex, rowSpan, colSpan); | |||
colIndex += colSpan; | |||
} | |||
// col span only | |||
else if (colSpan > 1) { | |||
spanCol(td, rowIndex, colIndex, colSpan); | |||
colIndex += colSpan; | |||
} | |||
// row span only | |||
else if (rowSpan > 1) { | |||
spanRow(td, rowIndex, colIndex, rowSpan); | |||
++colIndex; | |||
} | |||
// no span | |||
else { | |||
createCell(td, getOrCreateRow(rowIndex), colIndex).setCellValue(td.text()); | |||
++colIndex; | |||
} | |||
} | |||
++rowIndex; | |||
} | |||
} | |||
public Workbook createSheet(String html, Workbook workbook) { | |||
Elements els = Jsoup.parseBodyFragment(html).select("table"); | |||
Map<String, Sheet> sheets = new HashMap<String, Sheet>(); | |||
Map<String, Integer> maxrowMap = new HashMap<String, Integer>(); | |||
for (Element table : els) { | |||
String sheetName = table.attr("sheet"); | |||
if (StringUtils.isBlank(sheetName)) { | |||
LOGGER.error("table必须存在name属性!"); | |||
throw new RuntimeErrorException(null, "table必须存在name属性"); | |||
} | |||
if (sheets.containsKey(sheetName)) { | |||
maxRow = maxrowMap.get(sheetName); | |||
//cellStyles = csStyleMap.get(sheetName); | |||
//cellsOccupied = cellsOccupiedMap.get(sheetName); | |||
sheet = sheets.get(sheetName); | |||
} else { | |||
maxRow = 0; | |||
cellStyles.clear(); | |||
cellsOccupied.clear(); | |||
sheet = workbook.createSheet(sheetName); | |||
} | |||
//生成一个默认样式 | |||
defaultCellStyle = new ExcelExportStylerDefaultImpl(workbook).stringNoneStyle(workbook, | |||
false); | |||
processTable(table); | |||
maxrowMap.put(sheetName, maxRow); | |||
sheets.put(sheetName, sheet); | |||
} | |||
return workbook; | |||
} | |||
private void spanRow(Element td, int rowIndex, int colIndex, int rowSpan) { | |||
LOGGER.debug("Span Row , From Row [{}], Span [{}].", rowIndex, rowSpan); | |||
mergeRegion(rowIndex, rowIndex + rowSpan - 1, colIndex, colIndex); | |||
for (int i = 0; i < rowSpan; ++i) { | |||
Row row = getOrCreateRow(rowIndex + i); | |||
createCell(td, row, colIndex); | |||
cellsOccupied.put((rowIndex + i) + "_" + colIndex, true); | |||
} | |||
getOrCreateRow(rowIndex).getCell(colIndex).setCellValue(td.text()); | |||
} | |||
private void spanCol(Element td, int rowIndex, int colIndex, int colSpan) { | |||
LOGGER.debug("Span Col, From Col [{}], Span [{}].", colIndex, colSpan); | |||
mergeRegion(rowIndex, rowIndex, colIndex, colIndex + colSpan - 1); | |||
Row row = getOrCreateRow(rowIndex); | |||
for (int i = 0; i < colSpan; ++i) { | |||
createCell(td, row, colIndex + i); | |||
} | |||
row.getCell(colIndex).setCellValue(td.text()); | |||
} | |||
private void spanRowAndCol(Element td, int rowIndex, int colIndex, int rowSpan, int colSpan) { | |||
LOGGER.debug("Span Row And Col, From Row [{}], Span [{}].", rowIndex, rowSpan); | |||
LOGGER.debug("From Col [{}], Span [{}].", colIndex, colSpan); | |||
mergeRegion(rowIndex, rowIndex + rowSpan - 1, colIndex, colIndex + colSpan - 1); | |||
for (int i = 0; i < rowSpan; ++i) { | |||
Row row = getOrCreateRow(rowIndex + i); | |||
for (int j = 0; j < colSpan; ++j) { | |||
createCell(td, row, colIndex + j); | |||
cellsOccupied.put((rowIndex + i) + "_" + (colIndex + j), true); | |||
} | |||
} | |||
getOrCreateRow(rowIndex).getCell(colIndex).setCellValue(td.text()); | |||
} | |||
private Cell createCell(Element td, Row row, int colIndex) { | |||
Cell cell = row.getCell(colIndex); | |||
if (cell == null) { | |||
LOGGER.debug("Create Cell [{}][{}].", row.getRowNum(), colIndex); | |||
cell = row.createCell(colIndex); | |||
} | |||
return applyStyle(td, cell); | |||
} | |||
private Cell applyStyle(Element td, Cell cell) { | |||
String style = td.attr(HtmlCssConstant.STYLE); | |||
CellStyle cellStyle = null; | |||
if (StringUtils.isNotBlank(style)) { | |||
CellStyleEntity styleEntity = cssParse.parseStyle(style.trim()); | |||
cellStyle = cellStyles.get(styleEntity.toString()); | |||
if (cellStyle == null) { | |||
LOGGER.debug("No Cell Style Found In Cache, Parse New Style."); | |||
cellStyle = cell.getRow().getSheet().getWorkbook().createCellStyle(); | |||
cellStyle.cloneStyleFrom(defaultCellStyle); | |||
for (ICssConvertToExcel cssConvert : STYLE_APPLIERS) { | |||
cssConvert.convertToExcel(cell, cellStyle, styleEntity); | |||
} | |||
cellStyles.put(styleEntity.toString(), cellStyle); | |||
} | |||
for (ICssConvertToExcel cssConvert : SHEET_APPLIERS) { | |||
cssConvert.convertToExcel(cell, cellStyle, styleEntity); | |||
} | |||
if (cellStyles.size() >= 4000) { | |||
LOGGER.info( | |||
"Custom Cell Style Exceeds 4000, Could Not Create New Style, Use Default Style."); | |||
cellStyle = defaultCellStyle; | |||
} | |||
} else { | |||
LOGGER.debug("Style is null ,Use Default Cell Style."); | |||
cellStyle = defaultCellStyle; | |||
} | |||
cell.setCellStyle(cellStyle); | |||
return cell; | |||
} | |||
private Row getOrCreateRow(int rowIndex) { | |||
Row row = sheet.getRow(rowIndex); | |||
if (row == null) { | |||
LOGGER.debug("Create New Row [{}].", rowIndex); | |||
row = sheet.createRow(rowIndex); | |||
if (rowIndex > maxRow) { | |||
maxRow = rowIndex; | |||
} | |||
} | |||
return row; | |||
} | |||
private void mergeRegion(int firstRow, int lastRow, int firstCol, int lastCol) { | |||
LOGGER.debug("Merge Region, From Row [{}], To [{}].", firstRow, lastRow); | |||
LOGGER.debug("From Col [{}], To [{}].", firstCol, lastCol); | |||
sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol)); | |||
} | |||
} |
@@ -1,31 +0,0 @@ | |||
/** | |||
* Copyright 2013-2015 JueYue (qrb.jueyue@gmail.com) | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
* you may not use this file except in compliance with the License. | |||
* You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
package org.jeecgframework.poi.excel.html.css; | |||
import org.apache.poi.ss.usermodel.Cell; | |||
import org.jeecgframework.poi.excel.html.entity.CellStyleEntity; | |||
public class CssConverImpl implements ICssConvertToHtml, ICssConvertToExcel { | |||
@Override | |||
public void convertToExcel(Cell cell, CellStyleEntity style) { | |||
} | |||
@Override | |||
public void convertToHtml(Cell cell, CellStyleEntity entity) { | |||
} | |||
} |
@@ -0,0 +1,81 @@ | |||
package org.jeecgframework.poi.excel.html.css; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.jeecgframework.poi.excel.html.entity.CellStyleBorderEntity; | |||
import org.jeecgframework.poi.excel.html.entity.CellStyleEntity; | |||
import org.jeecgframework.poi.excel.html.entity.HtmlCssConstant; | |||
import org.jeecgframework.poi.util.PoiCssUtils; | |||
/** | |||
* 把Css样式解析成对应的Model | |||
* @author JueYue | |||
* 2017年3月19日 | |||
*/ | |||
public class CssParseServer { | |||
public CellStyleEntity parseStyle(String style) { | |||
Map<String, String> mapStyle = new HashMap<String, String>(); | |||
for (String s : style.split("\\s*;\\s*")) { | |||
if (StringUtils.isNotBlank(s)) { | |||
String[] ss = s.split("\\s*\\:\\s*"); | |||
if (ss.length == 2 && StringUtils.isNotBlank(ss[0]) | |||
&& StringUtils.isNotBlank(ss[1])) { | |||
String attrName = ss[0].toLowerCase(); | |||
String attrValue = ss[1]; | |||
// do not change font name | |||
if (!HtmlCssConstant.FONT.equals(attrName) | |||
&& !HtmlCssConstant.FONT_FAMILY.equals(attrName)) { | |||
attrValue = attrValue.toLowerCase(); | |||
} | |||
mapStyle.put(attrName, attrValue); | |||
} | |||
} | |||
} | |||
return mapToCellStyleEntity(mapStyle); | |||
} | |||
private CellStyleEntity mapToCellStyleEntity(Map<String, String> mapStyle) { | |||
CellStyleEntity entity = new CellStyleEntity(); | |||
entity.setAlign(mapStyle.get(HtmlCssConstant.TEXT_ALIGN)); | |||
entity.setVetical(mapStyle.get(HtmlCssConstant.VETICAL_ALIGN)); | |||
entity.setBackground(getBackground(mapStyle)); | |||
entity.setHeight(mapStyle.get(HtmlCssConstant.HEIGHT)); | |||
entity.setWidth(mapStyle.get(HtmlCssConstant.WIDTH)); | |||
// TODO 这里较为复杂,后期处理 | |||
/*CellStyleBorderEntity border = new CellStyleBorderEntity(); | |||
entity.setBorder(border); | |||
border.setBorderBottom(borderBottom);*/ | |||
return entity; | |||
} | |||
private String getBackground(Map<String, String> style) { | |||
Map<String, String> mapRtn = new HashMap<String, String>(); | |||
String bg = style.get(HtmlCssConstant.BACKGROUND); | |||
String bgColor = null; | |||
if (StringUtils.isNotBlank(bg)) { | |||
for (String bgAttr : bg.split("(?<=\\)|\\w|%)\\s+(?=\\w)")) { | |||
if ((bgColor = PoiCssUtils.processColor(bgAttr)) != null) { | |||
mapRtn.put(HtmlCssConstant.BACKGROUND_COLOR, bgColor); | |||
break; | |||
} | |||
} | |||
} | |||
bg = style.get(HtmlCssConstant.BACKGROUND_COLOR); | |||
if (StringUtils.isNotBlank(bg) && (bgColor = PoiCssUtils.processColor(bg)) != null) { | |||
mapRtn.put(HtmlCssConstant.BACKGROUND_COLOR, bgColor); | |||
} | |||
if (bgColor != null) { | |||
bgColor = mapRtn.get(HtmlCssConstant.BACKGROUND_COLOR); | |||
if (!"#ffffff".equals(bgColor)) { | |||
return mapRtn.get(HtmlCssConstant.BACKGROUND_COLOR); | |||
} | |||
} | |||
return null; | |||
} | |||
} |
@@ -16,6 +16,7 @@ | |||
package org.jeecgframework.poi.excel.html.css; | |||
import org.apache.poi.ss.usermodel.Cell; | |||
import org.apache.poi.ss.usermodel.CellStyle; | |||
import org.jeecgframework.poi.excel.html.entity.CellStyleEntity; | |||
/** | |||
@@ -24,11 +25,11 @@ import org.jeecgframework.poi.excel.html.entity.CellStyleEntity; | |||
* 2016年3月20日 下午4:53:04 | |||
*/ | |||
public interface ICssConvertToExcel { | |||
/** | |||
* 把HTML样式转换成Cell样式 | |||
* @param cell | |||
* @param style | |||
*/ | |||
public void convertToExcel(Cell cell, CellStyleEntity style); | |||
/** | |||
* 把HTML样式转换成Cell样式 | |||
* @param cell | |||
* @param style | |||
*/ | |||
public void convertToExcel(Cell cell, CellStyle cellStyle, CellStyleEntity style); | |||
} |
@@ -16,6 +16,7 @@ | |||
package org.jeecgframework.poi.excel.html.css; | |||
import org.apache.poi.ss.usermodel.Cell; | |||
import org.apache.poi.ss.usermodel.CellStyle; | |||
import org.jeecgframework.poi.excel.html.entity.CellStyleEntity; | |||
/** | |||
@@ -29,6 +30,6 @@ public interface ICssConvertToHtml { | |||
* @param cell | |||
* | |||
*/ | |||
public void convertToHtml(Cell cell, CellStyleEntity style); | |||
public String convertToHtml(Cell cell, CellStyle cellStyle, CellStyleEntity style); | |||
} |
@@ -0,0 +1,23 @@ | |||
package org.jeecgframework.poi.excel.html.css.impl; | |||
import org.apache.poi.ss.usermodel.Cell; | |||
import org.apache.poi.ss.usermodel.CellStyle; | |||
import org.jeecgframework.poi.excel.html.css.ICssConvertToExcel; | |||
import org.jeecgframework.poi.excel.html.css.ICssConvertToHtml; | |||
import org.jeecgframework.poi.excel.html.entity.CellStyleEntity; | |||
public class AlignCssConvertImpl implements ICssConvertToExcel, ICssConvertToHtml { | |||
@Override | |||
public String convertToHtml(Cell cell, CellStyle cellStyle, CellStyleEntity style) { | |||
return null; | |||
} | |||
@Override | |||
public void convertToExcel(Cell cell, CellStyle cellStyle, CellStyleEntity style) { | |||
} | |||
} |
@@ -0,0 +1,23 @@ | |||
package org.jeecgframework.poi.excel.html.css.impl; | |||
import org.apache.poi.ss.usermodel.Cell; | |||
import org.apache.poi.ss.usermodel.CellStyle; | |||
import org.jeecgframework.poi.excel.html.css.ICssConvertToExcel; | |||
import org.jeecgframework.poi.excel.html.css.ICssConvertToHtml; | |||
import org.jeecgframework.poi.excel.html.entity.CellStyleEntity; | |||
public class BackgroundCssConvertImpl implements ICssConvertToExcel, ICssConvertToHtml { | |||
@Override | |||
public String convertToHtml(Cell cell, CellStyle cellStyle, CellStyleEntity style) { | |||
return null; | |||
} | |||
@Override | |||
public void convertToExcel(Cell cell, CellStyle cellStyle, CellStyleEntity style) { | |||
} | |||
} |
@@ -29,26 +29,24 @@ import org.jeecgframework.poi.excel.html.entity.CellStyleEntity; | |||
*/ | |||
public class BorderCssConverImpl implements ICssConvertToExcel, ICssConvertToHtml { | |||
@Override | |||
public void convertToHtml(Cell cell, CellStyleEntity style) { | |||
} | |||
@Override | |||
public String convertToHtml(Cell cell, CellStyle cellStyle, CellStyleEntity style) { | |||
@Override | |||
public void convertToExcel(Cell cell, CellStyleEntity style) { | |||
CellStyle cellStyle = cell.getCellStyle(); | |||
if (cellStyle == null) { | |||
return; | |||
} | |||
CellStyleBorderEntity border = new CellStyleBorderEntity(); | |||
border.setBorderBottom(cellStyle.getBorderBottom()); | |||
border.setBorderBottomColor(cellStyle.getBottomBorderColor()); | |||
border.setBorderLeft(cellStyle.getBorderLeft()); | |||
border.setBorderLeftColor(cellStyle.getLeftBorderColor()); | |||
border.setBorderRight(cellStyle.getBorderRight()); | |||
border.setBorderRightColor(cellStyle.getRightBorderColor()); | |||
border.setBorderTop(cellStyle.getBorderTop()); | |||
border.setBorderTopColor(cellStyle.getTopBorderColor()); | |||
style.setBorder(border); | |||
} | |||
return null; | |||
} | |||
@Override | |||
public void convertToExcel(Cell cell, CellStyle cellStyle, CellStyleEntity style) { | |||
CellStyleBorderEntity border = new CellStyleBorderEntity(); | |||
border.setBorderBottom(cellStyle.getBorderBottom()); | |||
border.setBorderBottomColor(cellStyle.getBottomBorderColor()); | |||
border.setBorderLeft(cellStyle.getBorderLeft()); | |||
border.setBorderLeftColor(cellStyle.getLeftBorderColor()); | |||
border.setBorderRight(cellStyle.getBorderRight()); | |||
border.setBorderRightColor(cellStyle.getRightBorderColor()); | |||
border.setBorderTop(cellStyle.getBorderTop()); | |||
border.setBorderTopColor(cellStyle.getTopBorderColor()); | |||
style.setBorder(border); | |||
} | |||
} |
@@ -15,10 +15,15 @@ | |||
*/ | |||
package org.jeecgframework.poi.excel.html.css.impl; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.apache.poi.ss.usermodel.Cell; | |||
import org.apache.poi.ss.usermodel.CellStyle; | |||
import org.apache.poi.ss.usermodel.Row; | |||
import org.jeecgframework.poi.excel.html.css.ICssConvertToExcel; | |||
import org.jeecgframework.poi.excel.html.css.ICssConvertToHtml; | |||
import org.jeecgframework.poi.excel.html.entity.CellStyleEntity; | |||
import org.jeecgframework.poi.util.PoiCssUtils; | |||
/** | |||
* 行高转换实现类 | |||
@@ -27,14 +32,21 @@ import org.jeecgframework.poi.excel.html.entity.CellStyleEntity; | |||
*/ | |||
public class HeightCssConverImpl implements ICssConvertToExcel, ICssConvertToHtml { | |||
@Override | |||
public void convertToHtml(Cell cell, CellStyleEntity style) { | |||
style.setHeight(cell.getRow().getHeight()); | |||
} | |||
@Override | |||
public String convertToHtml(Cell cell, CellStyle cellStyle, CellStyleEntity style) { | |||
@Override | |||
public void convertToExcel(Cell cell, CellStyleEntity style) { | |||
return null; | |||
} | |||
} | |||
@Override | |||
public void convertToExcel(Cell cell, CellStyle cellStyle, CellStyleEntity style) { | |||
if (StringUtils.isNoneBlank(style.getHeight())) { | |||
int height = Math.round(PoiCssUtils.getInt(style.getHeight()) * 255 / 12.75F); | |||
Row row = cell.getRow(); | |||
if (height > row.getHeight()) { | |||
row.setHeight((short) height); | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,23 @@ | |||
package org.jeecgframework.poi.excel.html.css.impl; | |||
import org.apache.poi.ss.usermodel.Cell; | |||
import org.apache.poi.ss.usermodel.CellStyle; | |||
import org.jeecgframework.poi.excel.html.css.ICssConvertToExcel; | |||
import org.jeecgframework.poi.excel.html.css.ICssConvertToHtml; | |||
import org.jeecgframework.poi.excel.html.entity.CellStyleEntity; | |||
public class TextCssConvertImpl implements ICssConvertToExcel, ICssConvertToHtml { | |||
@Override | |||
public String convertToHtml(Cell cell, CellStyle cellStyle, CellStyleEntity style) { | |||
return null; | |||
} | |||
@Override | |||
public void convertToExcel(Cell cell, CellStyle cellStyle, CellStyleEntity style) { | |||
} | |||
} |
@@ -15,10 +15,14 @@ | |||
*/ | |||
package org.jeecgframework.poi.excel.html.css.impl; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.apache.poi.ss.usermodel.Cell; | |||
import org.apache.poi.ss.usermodel.CellStyle; | |||
import org.apache.poi.ss.usermodel.Sheet; | |||
import org.jeecgframework.poi.excel.html.css.ICssConvertToExcel; | |||
import org.jeecgframework.poi.excel.html.css.ICssConvertToHtml; | |||
import org.jeecgframework.poi.excel.html.entity.CellStyleEntity; | |||
import org.jeecgframework.poi.util.PoiCssUtils; | |||
/** | |||
* 列宽转换实现类 | |||
@@ -27,13 +31,25 @@ import org.jeecgframework.poi.excel.html.entity.CellStyleEntity; | |||
*/ | |||
public class WidthCssConverImpl implements ICssConvertToExcel, ICssConvertToHtml { | |||
@Override | |||
public void convertToHtml(Cell cell, CellStyleEntity style) { | |||
style.setWidth(cell.getRow().getSheet().getColumnWidth(cell.getColumnIndex())); | |||
} | |||
@Override | |||
public String convertToHtml(Cell cell, CellStyle cellStyle, CellStyleEntity style) { | |||
@Override | |||
public void convertToExcel(Cell cell, CellStyleEntity style) { | |||
} | |||
return null; | |||
} | |||
@Override | |||
public void convertToExcel(Cell cell, CellStyle cellStyle, CellStyleEntity style) { | |||
if (StringUtils.isNoneBlank(style.getWidth())) { | |||
int width = (int) Math.round(PoiCssUtils.getInt(style.getWidth()) * 2048 / 8.43F); | |||
Sheet sheet = cell.getSheet(); | |||
int colIndex = cell.getColumnIndex(); | |||
if (width > sheet.getColumnWidth(colIndex)) { | |||
if (width > 255 * 256) { | |||
width = 255 * 256; | |||
} | |||
sheet.setColumnWidth(colIndex, width); | |||
} | |||
} | |||
} | |||
} |
@@ -24,11 +24,11 @@ public class CellStyleEntity { | |||
/** | |||
* 宽 | |||
*/ | |||
private double width; | |||
private String width; | |||
/** | |||
* 高 | |||
*/ | |||
private double height; | |||
private String height; | |||
/** | |||
* 边框 | |||
*/ | |||
@@ -46,19 +46,19 @@ public class CellStyleEntity { | |||
*/ | |||
private String vetical; | |||
public double getWidth() { | |||
public String getWidth() { | |||
return width; | |||
} | |||
public void setWidth(double width) { | |||
public void setWidth(String width) { | |||
this.width = width; | |||
} | |||
public double getHeight() { | |||
public String getHeight() { | |||
return height; | |||
} | |||
public void setHeight(double height) { | |||
public void setHeight(String height) { | |||
this.height = height; | |||
} | |||
@@ -0,0 +1,48 @@ | |||
/** | |||
* Copyright 2013-2015 JueYue (qrb.jueyue@gmail.com) | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
* you may not use this file except in compliance with the License. | |||
* You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
package org.jeecgframework.poi.excel.html.entity; | |||
public interface HtmlCssConstant { | |||
// constants | |||
public final String PATTERN_LENGTH = "\\d*\\.?\\d+\\s*(?:em|ex|cm|mm|q|in|pt|pc|px)?"; | |||
public final String STYLE = "style"; | |||
// direction | |||
public final String TOP = "top"; | |||
public final String RIGHT = "right"; | |||
public final String BOTTOM = "bottom"; | |||
public final String LEFT = "left"; | |||
public final String WIDTH = "width"; | |||
public final String HEIGHT = "height"; | |||
public final String COLOR = "color"; | |||
public final String BORDER = "border"; | |||
public final String CENTER = "center"; | |||
public final String JUSTIFY = "justify"; | |||
public final String MIDDLE = "middle"; | |||
public final String FONT = "font"; | |||
public final String FONT_STYLE = "font-style"; | |||
public final String FONT_WEIGHT = "font-weight"; | |||
public final String FONT_SIZE = "font-size"; | |||
public final String FONT_FAMILY = "font-family"; | |||
public final String ITALIC = "italic"; | |||
public final String BOLD = "bold"; | |||
public final String NORMAL = "normal"; | |||
public final String TEXT_ALIGN = "text-align"; | |||
public final String VETICAL_ALIGN = "vertical-align"; | |||
public final String BACKGROUND = "background"; | |||
public final String BACKGROUND_COLOR = "background-color"; | |||
} |
@@ -0,0 +1,182 @@ | |||
package org.jeecgframework.poi.util; | |||
import java.util.Map; | |||
import java.awt.Color; | |||
import org.slf4j.Logger; | |||
import java.util.HashMap; | |||
import java.util.regex.Pattern; | |||
import java.util.regex.Matcher; | |||
import org.slf4j.LoggerFactory; | |||
import org.apache.poi.hssf.util.HSSFColor; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.apache.poi.hssf.usermodel.HSSFPalette; | |||
import org.apache.poi.hssf.usermodel.HSSFWorkbook; | |||
/** | |||
* @version 2.0.1 | |||
* @author Shaun Chyxion | |||
* @author JueYue | |||
*/ | |||
public class PoiCssUtils { | |||
private static final Logger log = LoggerFactory | |||
.getLogger(PoiCssUtils.class); | |||
// matches #rgb | |||
private static final String COLOR_PATTERN_VALUE_SHORT = "^(#(?:[a-f]|\\d){3})$"; | |||
// matches #rrggbb | |||
private static final String COLOR_PATTERN_VALUE_LONG = "^(#(?:[a-f]|\\d{2}){3})$"; | |||
// matches #rgb(r, g, b) | |||
private static final String COLOR_PATTERN_RGB = "^(rgb\\s*\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\))$"; | |||
// color name -> POI Color | |||
private static Map<String, HSSFColor> colors = new HashMap<String, HSSFColor>(); | |||
// static init | |||
static { | |||
for (Map.Entry<Integer, HSSFColor> color : HSSFColor.getIndexHash().entrySet()) { | |||
colors.put(colorName(color.getValue().getClass()), color.getValue()); | |||
} | |||
// light gray | |||
HSSFColor color = colors.get(colorName(HSSFColor.GREY_25_PERCENT.class)); | |||
colors.put("lightgray", color); | |||
colors.put("lightgrey", color); | |||
// silver | |||
colors.put("silver", colors.get(colorName(HSSFColor.GREY_40_PERCENT.class))); | |||
// darkgray | |||
color = colors.get(colorName(HSSFColor.GREY_50_PERCENT.class)); | |||
colors.put("darkgray", color); | |||
colors.put("darkgrey", color); | |||
// gray | |||
color = colors.get(colorName(HSSFColor.GREY_80_PERCENT.class)); | |||
colors.put("gray", color); | |||
colors.put("grey", color); | |||
} | |||
/** | |||
* get color name | |||
* @param color HSSFColor | |||
* @return color name | |||
*/ | |||
private static String colorName(Class<? extends HSSFColor> color) { | |||
return color.getSimpleName().replace("_", "").toLowerCase(); | |||
} | |||
/** | |||
* get int value of string | |||
* @param strValue string value | |||
* @return int value | |||
*/ | |||
public static int getInt(String strValue) { | |||
int value = 0; | |||
if (StringUtils.isNotBlank(strValue)) { | |||
Matcher m = Pattern.compile("^(\\d+)(?:\\w+|%)?$").matcher(strValue); | |||
if (m.find()) { | |||
value = Integer.parseInt(m.group(1)); | |||
} | |||
} | |||
return value; | |||
} | |||
/** | |||
* check number string | |||
* @param strValue string | |||
* @return true if string is number | |||
*/ | |||
public static boolean isNum(String strValue) { | |||
return StringUtils.isNotBlank(strValue) && strValue.matches("^\\d+(\\w+|%)?$"); | |||
} | |||
/** | |||
* process color | |||
* @param color color to process | |||
* @return color after process | |||
*/ | |||
public static String processColor(String color) { | |||
log.info("Process Color [{}].", color); | |||
String colorRtn = null; | |||
if (StringUtils.isNotBlank(color)) { | |||
HSSFColor poiColor = null; | |||
// #rgb -> #rrggbb | |||
if (color.matches(COLOR_PATTERN_VALUE_SHORT)) { | |||
log.debug("Short Hex Color [{}] Found.", color); | |||
StringBuffer sbColor = new StringBuffer(); | |||
Matcher m = Pattern.compile("([a-f]|\\d)").matcher(color); | |||
while (m.find()) { | |||
m.appendReplacement(sbColor, "$1$1"); | |||
} | |||
colorRtn = sbColor.toString(); | |||
log.debug("Translate Short Hex Color [{}] To [{}].", color, colorRtn); | |||
} | |||
// #rrggbb | |||
else if (color.matches(COLOR_PATTERN_VALUE_LONG)) { | |||
colorRtn = color; | |||
log.debug("Hex Color [{}] Found, Return.", color); | |||
} | |||
// rgb(r, g, b) | |||
else if (color.matches(COLOR_PATTERN_RGB)) { | |||
Matcher m = Pattern.compile(COLOR_PATTERN_RGB).matcher(color); | |||
if (m.matches()) { | |||
log.debug("RGB Color [{}] Found.", color); | |||
colorRtn = convertColor(calcColorValue(m.group(2)), calcColorValue(m.group(3)), | |||
calcColorValue(m.group(4))); | |||
log.debug("Translate RGB Color [{}] To Hex [{}].", color, colorRtn); | |||
} | |||
} | |||
// color name, red, green, ... | |||
else if ((poiColor = getColor(color)) != null) { | |||
log.debug("Color Name [{}] Found.", color); | |||
short[] t = poiColor.getTriplet(); | |||
colorRtn = convertColor(t[0], t[1], t[2]); | |||
log.debug("Translate Color Name [{}] To Hex [{}].", color, colorRtn); | |||
} | |||
} | |||
return colorRtn; | |||
} | |||
/** | |||
* parse color | |||
* @param workBook work book | |||
* @param color string color | |||
* @return HSSFColor | |||
*/ | |||
public static HSSFColor parseColor(HSSFWorkbook workBook, String color) { | |||
HSSFColor poiColor = null; | |||
if (StringUtils.isNotBlank(color)) { | |||
Color awtColor = Color.decode(color); | |||
if (awtColor != null) { | |||
int r = awtColor.getRed(); | |||
int g = awtColor.getGreen(); | |||
int b = awtColor.getBlue(); | |||
HSSFPalette palette = workBook.getCustomPalette(); | |||
poiColor = palette.findColor((byte) r, (byte) g, (byte) b); | |||
if (poiColor == null) { | |||
poiColor = palette.findSimilarColor(r, g, b); | |||
} | |||
} | |||
} | |||
return poiColor; | |||
} | |||
// -- | |||
// private methods | |||
private static HSSFColor getColor(String color) { | |||
return colors.get(color.replace("_", "")); | |||
} | |||
private static String convertColor(int r, int g, int b) { | |||
return String.format("#%02x%02x%02x", r, g, b); | |||
} | |||
private static int calcColorValue(String color) { | |||
int rtn = 0; | |||
// matches 64 or 64% | |||
Matcher m = Pattern.compile("^(\\d*\\.?\\d+)\\s*(%)?$").matcher(color); | |||
if (m.matches()) { | |||
// % not found | |||
if (m.group(2) == null) { | |||
rtn = Math.round(Float.parseFloat(m.group(1))) % 256; | |||
} else { | |||
rtn = Math.round(Float.parseFloat(m.group(1)) * 255 / 100) % 256; | |||
} | |||
} | |||
return rtn; | |||
} | |||
} |
@@ -17,5 +17,11 @@ | |||
<attribute name="maven.pomderived" value="true"/> | |||
</attributes> | |||
</classpathentry> | |||
<classpathentry kind="src" output="target/test-classes" path="src/test/java"> | |||
<attributes> | |||
<attribute name="optional" value="true"/> | |||
<attribute name="maven.pomderived" value="true"/> | |||
</attributes> | |||
</classpathentry> | |||
<classpathentry kind="output" path="target/classes"/> | |||
</classpath> |
@@ -159,6 +159,13 @@ | |||
<version>1.1.0.Final</version> | |||
</dependency> | |||
<!-- 读取Excel --> | |||
<dependency> | |||
<groupId>org.jsoup</groupId> | |||
<artifactId>jsoup</artifactId> | |||
<version>1.8.3</version> | |||
</dependency> | |||
<!-- 模块版本 --> | |||
<dependency> | |||
<groupId>org.jeecg</groupId> | |||