diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/HyperlinkRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/HyperlinkRecordHandler.java index 915abf6..99c3a80 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/HyperlinkRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/HyperlinkRecordHandler.java @@ -23,7 +23,7 @@ public class HyperlinkRecordHandler extends AbstractXlsRecordHandler implements public void processRecord(XlsReadContext xlsReadContext, Record record) { HyperlinkRecord hr = (HyperlinkRecord)record; CellExtra cellExtra = new CellExtra(CellExtraTypeEnum.HYPERLINK, hr.getAddress(), hr.getFirstRow(), - hr.getFirstColumn(), hr.getLastRow(), hr.getLastColumn()); + hr.getLastRow(), hr.getFirstColumn(), hr.getLastColumn()); xlsReadContext.xlsReadSheetHolder().setCellExtra(cellExtra); xlsReadContext.analysisEventProcessor().extra(xlsReadContext); } diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/MergeCellsRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/MergeCellsRecordHandler.java index 4689f2b..f9bf472 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/MergeCellsRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/MergeCellsRecordHandler.java @@ -27,7 +27,7 @@ public class MergeCellsRecordHandler extends AbstractXlsRecordHandler implements for (int i = 0; i < mcr.getNumAreas(); i++) { CellRangeAddress cellRangeAddress = mcr.getAreaAt(i); CellExtra cellExtra = new CellExtra(CellExtraTypeEnum.MERGE, null, cellRangeAddress.getFirstRow(), - cellRangeAddress.getFirstColumn(), cellRangeAddress.getLastRow(), cellRangeAddress.getLastColumn()); + cellRangeAddress.getLastRow(), cellRangeAddress.getFirstColumn(), cellRangeAddress.getLastColumn()); xlsReadContext.xlsReadSheetHolder().setCellExtra(cellExtra); xlsReadContext.analysisEventProcessor().extra(xlsReadContext); } diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java index 8ef0786..7ba521d 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java @@ -1,8 +1,5 @@ package com.alibaba.excel.analysis.v07.handlers; -import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_DATA_FORMAT_TAG; -import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_VALUE_TYPE_TAG; - import org.apache.poi.xssf.usermodel.XSSFCellStyle; import org.xml.sax.Attributes; @@ -24,7 +21,7 @@ public class CellTagHandler extends AbstractXlsxTagHandler { @Override public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) { XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder(); - xlsxReadSheetHolder.setColumnIndex(PositionUtils.getCol(attributes.getValue(ExcelXmlConstants.POSITION))); + xlsxReadSheetHolder.setColumnIndex(PositionUtils.getCol(attributes.getValue(ExcelXmlConstants.ATTRIBUTE_R))); // t="s" ,it's means String // t="str" ,it's means String,but does not need to be read in the 'sharedStrings.xml' @@ -33,12 +30,12 @@ public class CellTagHandler extends AbstractXlsxTagHandler { // t="e" ,it's means Error // t="n" ,it's means Number // t is null ,it's means Empty or Number - CellDataTypeEnum type = CellDataTypeEnum.buildFromCellType(attributes.getValue(CELL_VALUE_TYPE_TAG)); + CellDataTypeEnum type = CellDataTypeEnum.buildFromCellType(attributes.getValue(ExcelXmlConstants.ATTRIBUTE_T)); xlsxReadSheetHolder.setTempCellData(new CellData(type)); xlsxReadSheetHolder.setTempData(new StringBuilder()); // Put in data transformation information - String dateFormatIndex = attributes.getValue(CELL_DATA_FORMAT_TAG); + String dateFormatIndex = attributes.getValue(ExcelXmlConstants.ATTRIBUTE_S); if (dateFormatIndex != null) { int dateFormatIndexInteger = Integer.parseInt(dateFormatIndex); XSSFCellStyle xssfCellStyle = diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CountTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CountTagHandler.java index c1eb323..823bafb 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CountTagHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CountTagHandler.java @@ -1,9 +1,8 @@ package com.alibaba.excel.analysis.v07.handlers; -import static com.alibaba.excel.constant.ExcelXmlConstants.DIMENSION_REF; - import org.xml.sax.Attributes; +import com.alibaba.excel.constant.ExcelXmlConstants; import com.alibaba.excel.context.xlsx.XlsxReadContext; /** @@ -15,7 +14,7 @@ public class CountTagHandler extends AbstractXlsxTagHandler { @Override public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) { - String d = attributes.getValue(DIMENSION_REF); + String d = attributes.getValue(ExcelXmlConstants.ATTRIBUTE_REF); String totalStr = d.substring(d.indexOf(":") + 1, d.length()); String c = totalStr.toUpperCase().replaceAll("[A-Z]", ""); xlsxReadContext.readSheetHolder().setApproximateTotalRowNumber(Integer.parseInt(c)); diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java index 372a0a7..ee33266 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java @@ -21,7 +21,7 @@ public class RowTagHandler extends AbstractXlsxTagHandler { @Override public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) { xlsxReadContext.readRowHolder( - new ReadRowHolder(PositionUtils.getRowByRowTagt(attributes.getValue(ExcelXmlConstants.POSITION)), + new ReadRowHolder(PositionUtils.getRowByRowTagt(attributes.getValue(ExcelXmlConstants.ATTRIBUTE_R)), RowTypeEnum.DATA, xlsxReadContext.readSheetHolder().getGlobalConfiguration(), null)); } diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/XlsxRowHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/XlsxRowHandler.java index 0a4adb4..65eaa6a 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/XlsxRowHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/XlsxRowHandler.java @@ -24,18 +24,33 @@ import com.alibaba.excel.context.xlsx.XlsxReadContext; */ public class XlsxRowHandler extends DefaultHandler { private XlsxReadContext xlsxReadContext; - private static final Map XLSX_CELL_HANDLER_MAP = new HashMap(16); + private static final Map XLSX_CELL_HANDLER_MAP = new HashMap(32); static { - XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_FORMULA_TAG, new CellFormulaTagHandler()); - XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_INLINE_STRING_VALUE_TAG, - new CellInlineStringValueTagHandler()); - XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_TAG, new CellTagHandler()); - XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_VALUE_TAG, new CellValueTagHandler()); - XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.DIMENSION, new CountTagHandler()); - XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.HYPERLINK_TAG, new HyperlinkTagHandler()); - XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.MERGE_CELL_TAG, new MergeCellTagHandler()); - XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.ROW_TAG, new RowTagHandler()); + CellFormulaTagHandler cellFormulaTagHandler = new CellFormulaTagHandler(); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_FORMULA_TAG, cellFormulaTagHandler); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_FORMULA_TAG, cellFormulaTagHandler); + CellInlineStringValueTagHandler cellInlineStringValueTagHandler = new CellInlineStringValueTagHandler(); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_INLINE_STRING_VALUE_TAG, cellInlineStringValueTagHandler); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_INLINE_STRING_VALUE_TAG, cellInlineStringValueTagHandler); + CellTagHandler cellTagHandler = new CellTagHandler(); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_TAG, cellTagHandler); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_TAG, cellTagHandler); + CellValueTagHandler cellValueTagHandler = new CellValueTagHandler(); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_VALUE_TAG, cellValueTagHandler); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_VALUE_TAG, cellValueTagHandler); + CountTagHandler countTagHandler = new CountTagHandler(); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.DIMENSION_TAG, countTagHandler); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_DIMENSION_TAG, countTagHandler); + HyperlinkTagHandler hyperlinkTagHandler = new HyperlinkTagHandler(); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.HYPERLINK_TAG, hyperlinkTagHandler); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_HYPERLINK_TAG, hyperlinkTagHandler); + MergeCellTagHandler mergeCellTagHandler = new MergeCellTagHandler(); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.MERGE_CELL_TAG, mergeCellTagHandler); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_MERGE_CELL_TAG, mergeCellTagHandler); + RowTagHandler rowTagHandler = new RowTagHandler(); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.ROW_TAG, rowTagHandler); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_ROW_TAG, rowTagHandler); } public XlsxRowHandler(XlsxReadContext xlsxReadContext) { @@ -45,7 +60,7 @@ public class XlsxRowHandler extends DefaultHandler { @Override public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { XlsxTagHandler handler = XLSX_CELL_HANDLER_MAP.get(name); - if (handler == null) { + if (handler == null || !handler.support(xlsxReadContext)) { return; } xlsxReadContext.xlsxReadSheetHolder().getTagDeque().push(name); @@ -59,7 +74,7 @@ public class XlsxRowHandler extends DefaultHandler { return; } XlsxTagHandler handler = XLSX_CELL_HANDLER_MAP.get(currentTag); - if (handler == null) { + if (handler == null || !handler.support(xlsxReadContext)) { return; } handler.characters(xlsxReadContext, ch, start, length); @@ -68,7 +83,7 @@ public class XlsxRowHandler extends DefaultHandler { @Override public void endElement(String uri, String localName, String name) throws SAXException { XlsxTagHandler handler = XLSX_CELL_HANDLER_MAP.get(name); - if (handler == null) { + if (handler == null || !handler.support(xlsxReadContext)) { return; } handler.endElement(xlsxReadContext, name); diff --git a/src/main/java/com/alibaba/excel/annotation/write/style/ContentFontStyle.java b/src/main/java/com/alibaba/excel/annotation/write/style/ContentFontStyle.java new file mode 100644 index 0000000..cb8d3c5 --- /dev/null +++ b/src/main/java/com/alibaba/excel/annotation/write/style/ContentFontStyle.java @@ -0,0 +1,89 @@ +package com.alibaba.excel.annotation.write.style; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.apache.poi.common.usermodel.fonts.FontCharset; +import org.apache.poi.hssf.usermodel.HSSFPalette; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.IndexedColors; + +/** + * Custom content styles. + * + * @author Jiaju Zhuang + */ +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface ContentFontStyle { + + /** + * The name for the font (i.e. Arial) + */ + String fontName(); + + /** + * Height in the familiar unit of measure - points + */ + short fontHeightInPoints() default -1; + + /** + * Whether to use italics or not + */ + boolean italic() default false; + + /** + * Whether to use a strikeout horizontal line through the text or not + */ + boolean strikeout() default false; + + /** + * The color for the font + * + * @see Font#COLOR_NORMAL + * @see Font#COLOR_RED + * @see HSSFPalette#getColor(short) + * @see IndexedColors + */ + short color() default -1; + + /** + * Set normal,super or subscript. + * + * @see Font#SS_NONE + * @see Font#SS_SUPER + * @see Font#SS_SUB + */ + short typeOffset() default -1; + + /** + * set type of text underlining to use + * + * @see Font#U_NONE + * @see Font#U_SINGLE + * @see Font#U_DOUBLE + * @see Font#U_SINGLE_ACCOUNTING + * @see Font#U_DOUBLE_ACCOUNTING + */ + + byte underline() default -1; + + /** + * Set character-set to use. + * + * @see FontCharset + * @see Font#ANSI_CHARSET + * @see Font#DEFAULT_CHARSET + * @see Font#SYMBOL_CHARSET + */ + int charset() default -1; + + /** + * Bold + */ + boolean bold() default false; +} diff --git a/src/main/java/com/alibaba/excel/annotation/write/style/ContentLoopMerge.java b/src/main/java/com/alibaba/excel/annotation/write/style/ContentLoopMerge.java new file mode 100644 index 0000000..af7bcec --- /dev/null +++ b/src/main/java/com/alibaba/excel/annotation/write/style/ContentLoopMerge.java @@ -0,0 +1,31 @@ +package com.alibaba.excel.annotation.write.style; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The regions of the loop merge + * + * @author Jiaju Zhuang + */ +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface ContentLoopMerge { + /** + * Each row + * + * @return + */ + int eachRow() default -1; + + /** + * Extend column + * + * @return + */ + int columnExtend() default 1; +} diff --git a/src/main/java/com/alibaba/excel/annotation/write/style/ContentStyle.java b/src/main/java/com/alibaba/excel/annotation/write/style/ContentStyle.java new file mode 100644 index 0000000..1cece9b --- /dev/null +++ b/src/main/java/com/alibaba/excel/annotation/write/style/ContentStyle.java @@ -0,0 +1,159 @@ +package com.alibaba.excel.annotation.write.style; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.apache.poi.ss.usermodel.BorderStyle; +import org.apache.poi.ss.usermodel.BuiltinFormats; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IgnoredErrorType; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.VerticalAlignment; + +/** + * Custom content styles + * + * @author Jiaju Zhuang + */ +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface ContentStyle { + /** + * Set the data format (must be a valid format). Built in formats are defined at {@link BuiltinFormats}. + */ + short dataFormat(); + + /** + * Set the cell's using this style to be hidden + */ + boolean hidden(); + + /** + * Set the cell's using this style to be locked + */ + boolean locked(); + + /** + * Turn on or off "Quote Prefix" or "123 Prefix" for the style, which is used to tell Excel that the thing which + * looks like a number or a formula shouldn't be treated as on. Turning this on is somewhat (but not completely, see + * {@link IgnoredErrorType}) like prefixing the cell value with a ' in Excel + */ + boolean quotePrefix(); + + /** + * Set the type of horizontal alignment for the cell + */ + HorizontalAlignment horizontalAlignment(); + + /** + * Set whether the text should be wrapped. Setting this flag to true make all content visible within a + * cell by displaying it on multiple lines + * + */ + boolean wrapped(); + + /** + * Set the type of vertical alignment for the cell + */ + VerticalAlignment verticalAlignment(); + + /** + * Set the degree of rotation for the text in the cell. + * + * Note: HSSF uses values from -90 to 90 degrees, whereas XSSF uses values from 0 to 180 degrees. The + * implementations of this method will map between these two value-ranges accordingly, however the corresponding + * getter is returning values in the range mandated by the current type of Excel file-format that this CellStyle is + * applied to. + */ + short rotation(); + + /** + * Set the number of spaces to indent the text in the cell + */ + short indent(); + + /** + * Set the type of border to use for the left border of the cell + */ + BorderStyle borderLeft(); + + /** + * Set the type of border to use for the right border of the cell + */ + BorderStyle borderRight(); + + /** + * Set the type of border to use for the top border of the cell + */ + BorderStyle borderTop(); + + /** + * Set the type of border to use for the bottom border of the cell + */ + BorderStyle borderBottom(); + + /** + * Set the color to use for the left border + * + * @see IndexedColors + */ + short leftBorderColor(); + + /** + * Set the color to use for the right border + * + * @see IndexedColors + * + */ + short rightBorderColor(); + + /** + * Set the color to use for the top border + * + * @see IndexedColors + * + */ + short topBorderColor(); + + /** + * Set the color to use for the bottom border + * + * @see IndexedColors + * + */ + short bottomBorderColor(); + + /** + * Setting to one fills the cell with the foreground color... No idea about other values + * + * @see FillPatternType#SOLID_FOREGROUND + */ + FillPatternType fillPatternType(); + + /** + * Set the background fill color. + * + * @see IndexedColors + * + */ + short fillBackgroundColor(); + + /** + * Set the foreground fill color Note: Ensure Foreground color is set prior to background color. + * + * @see IndexedColors + * + */ + short fillForegroundColor(); + + /** + * Controls if the Cell should be auto-sized to shrink to fit if the text is too long + */ + boolean shrinkToFit(); + +} diff --git a/src/main/java/com/alibaba/excel/annotation/write/style/HeadFontStyle.java b/src/main/java/com/alibaba/excel/annotation/write/style/HeadFontStyle.java new file mode 100644 index 0000000..907a44b --- /dev/null +++ b/src/main/java/com/alibaba/excel/annotation/write/style/HeadFontStyle.java @@ -0,0 +1,89 @@ +package com.alibaba.excel.annotation.write.style; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.apache.poi.common.usermodel.fonts.FontCharset; +import org.apache.poi.hssf.usermodel.HSSFPalette; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.IndexedColors; + +/** + * Custom header styles. + * + * @author Jiaju Zhuang + */ +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface HeadFontStyle { + + /** + * The name for the font (i.e. Arial) + */ + String fontName(); + + /** + * Height in the familiar unit of measure - points + */ + short fontHeightInPoints() default -1; + + /** + * Whether to use italics or not + */ + boolean italic() default false; + + /** + * Whether to use a strikeout horizontal line through the text or not + */ + boolean strikeout() default false; + + /** + * The color for the font + * + * @see Font#COLOR_NORMAL + * @see Font#COLOR_RED + * @see HSSFPalette#getColor(short) + * @see IndexedColors + */ + short color() default -1; + + /** + * Set normal,super or subscript. + * + * @see Font#SS_NONE + * @see Font#SS_SUPER + * @see Font#SS_SUB + */ + short typeOffset() default -1; + + /** + * set type of text underlining to use + * + * @see Font#U_NONE + * @see Font#U_SINGLE + * @see Font#U_DOUBLE + * @see Font#U_SINGLE_ACCOUNTING + * @see Font#U_DOUBLE_ACCOUNTING + */ + + byte underline() default -1; + + /** + * Set character-set to use. + * + * @see FontCharset + * @see Font#ANSI_CHARSET + * @see Font#DEFAULT_CHARSET + * @see Font#SYMBOL_CHARSET + */ + int charset() default -1; + + /** + * Bold + */ + boolean bold() default false; +} diff --git a/src/main/java/com/alibaba/excel/annotation/write/style/HeadStyle.java b/src/main/java/com/alibaba/excel/annotation/write/style/HeadStyle.java new file mode 100644 index 0000000..10252a7 --- /dev/null +++ b/src/main/java/com/alibaba/excel/annotation/write/style/HeadStyle.java @@ -0,0 +1,159 @@ +package com.alibaba.excel.annotation.write.style; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.apache.poi.ss.usermodel.BorderStyle; +import org.apache.poi.ss.usermodel.BuiltinFormats; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IgnoredErrorType; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.VerticalAlignment; + +/** + * Custom header styles + * + * @author Jiaju Zhuang + */ +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface HeadStyle { + /** + * Set the data format (must be a valid format). Built in formats are defined at {@link BuiltinFormats}. + */ + short dataFormat() default -1; + + /** + * Set the cell's using this style to be hidden + */ + boolean hidden() default false; + + /** + * Set the cell's using this style to be locked + */ + boolean locked() default false; + + /** + * Turn on or off "Quote Prefix" or "123 Prefix" for the style, which is used to tell Excel that the thing which + * looks like a number or a formula shouldn't be treated as on. Turning this on is somewhat (but not completely, see + * {@link IgnoredErrorType}) like prefixing the cell value with a ' in Excel + */ + boolean quotePrefix() default false; + + /** + * Set the type of horizontal alignment for the cell + */ + HorizontalAlignment horizontalAlignment(); + + /** + * Set whether the text should be wrapped. Setting this flag to true make all content visible within a + * cell by displaying it on multiple lines + * + */ + boolean wrapped() default false; + + /** + * Set the type of vertical alignment for the cell + */ + VerticalAlignment verticalAlignment(); + + /** + * Set the degree of rotation for the text in the cell. + * + * Note: HSSF uses values from -90 to 90 degrees, whereas XSSF uses values from 0 to 180 degrees. The + * implementations of this method will map between these two value-ranges accordingly, however the corresponding + * getter is returning values in the range mandated by the current type of Excel file-format that this CellStyle is + * applied to. + */ + short rotation() default -1; + + /** + * Set the number of spaces to indent the text in the cell + */ + short indent() default -1; + + /** + * Set the type of border to use for the left border of the cell + */ + BorderStyle borderLeft(); + + /** + * Set the type of border to use for the right border of the cell + */ + BorderStyle borderRight(); + + /** + * Set the type of border to use for the top border of the cell + */ + BorderStyle borderTop(); + + /** + * Set the type of border to use for the bottom border of the cell + */ + BorderStyle borderBottom(); + + /** + * Set the color to use for the left border + * + * @see IndexedColors + */ + short leftBorderColor() default -1; + + /** + * Set the color to use for the right border + * + * @see IndexedColors + * + */ + short rightBorderColor() default -1; + + /** + * Set the color to use for the top border + * + * @see IndexedColors + * + */ + short topBorderColor() default -1; + + /** + * Set the color to use for the bottom border + * + * @see IndexedColors + * + */ + short bottomBorderColor() default -1; + + /** + * Setting to one fills the cell with the foreground color... No idea about other values + * + * @see FillPatternType#SOLID_FOREGROUND + */ + FillPatternType fillPatternType(); + + /** + * Set the background fill color. + * + * @see IndexedColors + * + */ + short fillBackgroundColor() default -1; + + /** + * Set the foreground fill color Note: Ensure Foreground color is set prior to background color. + * + * @see IndexedColors + * + */ + short fillForegroundColor() default -1; + + /** + * Controls if the Cell should be auto-sized to shrink to fit if the text is too long + */ + boolean shrinkToFit() default false; + +} diff --git a/src/main/java/com/alibaba/excel/annotation/write/style/OnceAbsoluteMerge.java b/src/main/java/com/alibaba/excel/annotation/write/style/OnceAbsoluteMerge.java new file mode 100644 index 0000000..6c3a148 --- /dev/null +++ b/src/main/java/com/alibaba/excel/annotation/write/style/OnceAbsoluteMerge.java @@ -0,0 +1,45 @@ +package com.alibaba.excel.annotation.write.style; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Merge the cells once + * + * @author Jiaju Zhuang + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface OnceAbsoluteMerge { + /** + * First row + * + * @return + */ + int firstRowIndex() default -1; + + /** + * Last row + * + * @return + */ + int lastRowIndex() default -1; + + /** + * First column + * + * @return + */ + int firstColumnIndex() default -1; + + /** + * Last row + * + * @return + */ + int lastColumnIndex() default -1; +} diff --git a/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java b/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java index 5cb6662..38c2005 100644 --- a/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java +++ b/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java @@ -4,37 +4,54 @@ package com.alibaba.excel.constant; * @author jipengfei */ public class ExcelXmlConstants { - public static final String DIMENSION = "dimension"; - public static final String DIMENSION_REF = "ref"; - public static final String POSITION = "r"; - + public static final String DIMENSION_TAG = "dimension"; public static final String ROW_TAG = "row"; - public static final String CELL_TAG = "c"; - public static final String CELL_VALUE_TYPE_TAG = "t"; - /** - * Number formatted label - */ - public static final String CELL_DATA_FORMAT_TAG = "s"; public static final String CELL_FORMULA_TAG = "f"; public static final String CELL_VALUE_TAG = "v"; /** * When the data is "inlineStr" his tag is "t" */ public static final String CELL_INLINE_STRING_VALUE_TAG = "t"; - + public static final String CELL_TAG = "c"; public static final String MERGE_CELL_TAG = "mergeCell"; public static final String HYPERLINK_TAG = "hyperlink"; + public static final String X_DIMENSION_TAG = "x:dimension"; + public static final String X_ROW_TAG = "x:row"; + public static final String X_CELL_FORMULA_TAG = "x:f"; + public static final String X_CELL_VALUE_TAG = "x:v"; /** - * Cell range split + * When the data is "inlineStr" his tag is "t" */ - public static final String CELL_RANGE_SPLIT = ":"; + public static final String X_CELL_INLINE_STRING_VALUE_TAG = "x:t"; + public static final String X_CELL_TAG = "x:c"; + public static final String X_MERGE_CELL_TAG = "x:mergeCell"; + public static final String X_HYPERLINK_TAG = "x:hyperlink"; + + /** + * s attribute + */ + public static final String ATTRIBUTE_S = "s"; /** * ref attribute */ public static final String ATTRIBUTE_REF = "ref"; + /** + * r attribute + */ + public static final String ATTRIBUTE_R = "r"; + /** + * t attribute + */ + public static final String ATTRIBUTE_T = "t"; /** * location attribute */ public static final String ATTRIBUTE_LOCATION = "location"; + + /** + * Cell range split + */ + public static final String CELL_RANGE_SPLIT = ":"; + } diff --git a/src/main/java/com/alibaba/excel/metadata/CellExtra.java b/src/main/java/com/alibaba/excel/metadata/CellExtra.java index 3a9c2b3..937b9ac 100644 --- a/src/main/java/com/alibaba/excel/metadata/CellExtra.java +++ b/src/main/java/com/alibaba/excel/metadata/CellExtra.java @@ -23,14 +23,14 @@ public class CellExtra extends AbstractCell { * First row index,if this object is an interval */ private Integer firstRowIndex; - /** - * First column index,if this object is an interval - */ - private Integer firstColumnIndex; /** * Last row index,if this object is an interval */ private Integer lastRowIndex; + /** + * First column index,if this object is an interval + */ + private Integer firstColumnIndex; /** * Last column index,if this object is an interval */ @@ -55,11 +55,11 @@ public class CellExtra extends AbstractCell { } public CellExtra(CellExtraTypeEnum type, String text, Integer rowIndex, Integer columnIndex) { - this(type, text, rowIndex, columnIndex, rowIndex, columnIndex); + this(type, text, rowIndex, rowIndex, columnIndex, columnIndex); } - public CellExtra(CellExtraTypeEnum type, String text, Integer firstRowIndex, Integer firstColumnIndex, - Integer lastRowIndex, Integer lastColumnIndex) { + public CellExtra(CellExtraTypeEnum type, String text, Integer firstRowIndex, Integer lastRowIndex, + Integer firstColumnIndex, Integer lastColumnIndex) { super(); setRowIndex(firstRowIndex); setColumnIndex(firstColumnIndex); diff --git a/src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java b/src/main/java/com/alibaba/excel/write/handler/AbstractCellWriteHandler.java similarity index 58% rename from src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java rename to src/main/java/com/alibaba/excel/write/handler/AbstractCellWriteHandler.java index b661c12..3f42046 100644 --- a/src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java +++ b/src/main/java/com/alibaba/excel/write/handler/AbstractCellWriteHandler.java @@ -1,23 +1,22 @@ -package com.alibaba.excel.write.merge; +package com.alibaba.excel.write.handler; import java.util.List; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.Head; -import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder; /** - * Merge strategy + * Abstract cell write handler * * @author Jiaju Zhuang - */ -public abstract class AbstractMergeStrategy implements CellWriteHandler { + **/ +public abstract class AbstractCellWriteHandler implements CellWriteHandler { + @Override public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) { @@ -26,24 +25,13 @@ public abstract class AbstractMergeStrategy implements CellWriteHandler { @Override public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, - Head head, Integer relativeRowIndex, Boolean isHead) {} + Head head, Integer relativeRowIndex, Boolean isHead) { + + } @Override public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { - if (isHead) { - return; - } - merge(writeSheetHolder.getSheet(), cell, head, relativeRowIndex); - } - /** - * merge - * - * @param sheet - * @param cell - * @param head - * @param relativeRowIndex - */ - protected abstract void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex); + } } diff --git a/src/main/java/com/alibaba/excel/write/handler/AbstractRowWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/AbstractRowWriteHandler.java new file mode 100644 index 0000000..d1e8c3a --- /dev/null +++ b/src/main/java/com/alibaba/excel/write/handler/AbstractRowWriteHandler.java @@ -0,0 +1,31 @@ +package com.alibaba.excel.write.handler; + +import org.apache.poi.ss.usermodel.Row; + +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; + +/** + * Abstract row write handler + * + * @author Jiaju Zhuang + **/ +public abstract class AbstractRowWriteHandler implements RowWriteHandler { + @Override + public void beforeRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Integer rowIndex, + Integer relativeRowIndex, Boolean isHead) { + + } + + @Override + public void afterRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, + Integer relativeRowIndex, Boolean isHead) { + + } + + @Override + public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, + Integer relativeRowIndex, Boolean isHead) { + + } +} diff --git a/src/main/java/com/alibaba/excel/write/handler/AbstractSheetWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/AbstractSheetWriteHandler.java new file mode 100644 index 0000000..76f4c84 --- /dev/null +++ b/src/main/java/com/alibaba/excel/write/handler/AbstractSheetWriteHandler.java @@ -0,0 +1,21 @@ +package com.alibaba.excel.write.handler; + +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; + +/** + * Abstract sheet write handler + * + * @author Jiaju Zhuang + **/ +public abstract class AbstractSheetWriteHandler implements SheetWriteHandler { + @Override + public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { + + } + + @Override + public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { + + } +} diff --git a/src/main/java/com/alibaba/excel/write/handler/AbstractWorkbookWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/AbstractWorkbookWriteHandler.java new file mode 100644 index 0000000..baad392 --- /dev/null +++ b/src/main/java/com/alibaba/excel/write/handler/AbstractWorkbookWriteHandler.java @@ -0,0 +1,26 @@ +package com.alibaba.excel.write.handler; + +import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; + +/** + * Abstract workbook write handler + * + * @author Jiaju Zhuang + **/ +public abstract class AbstractWorkbookWriteHandler implements WorkbookWriteHandler { + + @Override + public void beforeWorkbookCreate() { + + } + + @Override + public void afterWorkbookCreate(WriteWorkbookHolder writeWorkbookHolder) { + + } + + @Override + public void afterWorkbookDispose(WriteWorkbookHolder writeWorkbookHolder) { + + } +} diff --git a/src/main/java/com/alibaba/excel/write/merge/LoopMergeStrategy.java b/src/main/java/com/alibaba/excel/write/merge/LoopMergeStrategy.java index 615e408..9c9ece1 100644 --- a/src/main/java/com/alibaba/excel/write/merge/LoopMergeStrategy.java +++ b/src/main/java/com/alibaba/excel/write/merge/LoopMergeStrategy.java @@ -1,58 +1,64 @@ package com.alibaba.excel.write.merge; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.util.CellRangeAddress; -import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.write.handler.AbstractRowWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; /** * The regions of the loop merge * * @author Jiaju Zhuang */ -public class LoopMergeStrategy extends AbstractMergeStrategy { +public class LoopMergeStrategy extends AbstractRowWriteHandler { + /** + * Each row + */ private int eachRow; - private int columnCount; + /** + * Extend column + */ + private int columnExtend; + /** + * The number of the current column + */ private int columnIndex; public LoopMergeStrategy(int eachRow, int columnIndex) { this(eachRow, 1, columnIndex); } - public LoopMergeStrategy(int eachRow, int columnCount, int columnIndex) { + public LoopMergeStrategy(int eachRow, int columnExtend, int columnIndex) { if (eachRow < 1) { throw new IllegalArgumentException("EachRows must be greater than 1"); } - if (columnCount < 1) { - throw new IllegalArgumentException("ColumnCount must be greater than 1"); + if (columnExtend < 1) { + throw new IllegalArgumentException("ColumnExtend must be greater than 1"); } - if (columnCount == 1 && eachRow == 1) { - throw new IllegalArgumentException("ColumnCount or eachRows must be greater than 1"); + if (columnExtend == 1 && eachRow == 1) { + throw new IllegalArgumentException("ColumnExtend or eachRows must be greater than 1"); } if (columnIndex < 0) { throw new IllegalArgumentException("ColumnIndex must be greater than 0"); } this.eachRow = eachRow; - this.columnCount = columnCount; + this.columnExtend = columnExtend; this.columnIndex = columnIndex; } @Override - protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) { - if (relativeRowIndex == null) { + public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, + Integer relativeRowIndex, Boolean isHead) { + if (isHead) { return; } - Integer currentColumnIndex; - if (head != null) { - currentColumnIndex = head.getColumnIndex(); - } else { - currentColumnIndex = cell.getColumnIndex(); - } - if (currentColumnIndex == columnIndex && relativeRowIndex % eachRow == 0) { - CellRangeAddress cellRangeAddress = new CellRangeAddress(cell.getRowIndex(), - cell.getRowIndex() + eachRow - 1, cell.getColumnIndex(), cell.getColumnIndex() + columnCount - 1); - sheet.addMergedRegionUnsafe(cellRangeAddress); + if (relativeRowIndex % eachRow == 0) { + CellRangeAddress cellRangeAddress = new CellRangeAddress(row.getRowNum(), row.getRowNum() + eachRow - 1, + columnIndex, columnIndex + columnExtend - 1); + writeSheetHolder.getSheet().addMergedRegionUnsafe(cellRangeAddress); } } + } diff --git a/src/main/java/com/alibaba/excel/write/merge/OnceAbsoluteMergeStrategy.java b/src/main/java/com/alibaba/excel/write/merge/OnceAbsoluteMergeStrategy.java index be05e22..71002ef 100644 --- a/src/main/java/com/alibaba/excel/write/merge/OnceAbsoluteMergeStrategy.java +++ b/src/main/java/com/alibaba/excel/write/merge/OnceAbsoluteMergeStrategy.java @@ -1,21 +1,32 @@ package com.alibaba.excel.write.merge; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.util.CellRangeAddress; -import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.write.handler.AbstractSheetWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; /** * It only merges once when create cell(firstRowIndex,lastRowIndex) * * @author Jiaju Zhuang */ -public class OnceAbsoluteMergeStrategy extends AbstractMergeStrategy { - +public class OnceAbsoluteMergeStrategy extends AbstractSheetWriteHandler { + /** + * First row + */ private int firstRowIndex; + /** + * Last row + */ private int lastRowIndex; + /** + * First column + */ private int firstColumnIndex; + /** + * Last row + */ private int lastColumnIndex; public OnceAbsoluteMergeStrategy(int firstRowIndex, int lastRowIndex, int firstColumnIndex, int lastColumnIndex) { @@ -29,11 +40,9 @@ public class OnceAbsoluteMergeStrategy extends AbstractMergeStrategy { } @Override - protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) { - if (cell.getRowIndex() == firstRowIndex && cell.getColumnIndex() == firstColumnIndex) { - CellRangeAddress cellRangeAddress = - new CellRangeAddress(firstRowIndex, lastRowIndex, firstColumnIndex, lastColumnIndex); - sheet.addMergedRegionUnsafe(cellRangeAddress); - } + public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { + CellRangeAddress cellRangeAddress = + new CellRangeAddress(firstRowIndex, lastRowIndex, firstColumnIndex, lastColumnIndex); + writeSheetHolder.getSheet().addMergedRegionUnsafe(cellRangeAddress); } } diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java b/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java index 30325d1..6c9bd8d 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java @@ -1,15 +1,24 @@ package com.alibaba.easyexcel.test.temp; import java.io.File; +import java.util.ArrayList; +import java.util.Date; import java.util.List; import org.apache.poi.hssf.util.CellReference; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.IndexedColors; import org.junit.Ignore; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.alibaba.easyexcel.test.demo.write.DemoData; +import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.write.metadata.style.WriteCellStyle; +import com.alibaba.excel.write.metadata.style.WriteFont; +import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; import com.alibaba.fastjson.JSON; /** @@ -32,6 +41,47 @@ public class Lock2Test { } } + @Test + public void write() throws Exception { + String fileName = TestFileUtil.getPath() + "styleWrite" + System.currentTimeMillis() + ".xlsx"; + // 头的策略 + WriteCellStyle headWriteCellStyle = new WriteCellStyle(); + // 背景设置为红色 + headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex()); + WriteFont headWriteFont = new WriteFont(); + headWriteFont.setFontHeightInPoints((short)20); + headWriteCellStyle.setWriteFont(headWriteFont); + // 内容的策略 + WriteCellStyle contentWriteCellStyle = new WriteCellStyle(); + // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定 + contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND); + // 背景绿色 + contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex()); + WriteFont contentWriteFont = new WriteFont(); + // 字体大小 + contentWriteFont.setFontHeightInPoints((short)20); + contentWriteCellStyle.setWriteFont(contentWriteFont); + // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现 + HorizontalCellStyleStrategy horizontalCellStyleStrategy = + new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle); + + // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 + EasyExcel.write(fileName, DemoData.class).registerWriteHandler(horizontalCellStyleStrategy).sheet("模板") + .doWrite(data()); + } + + private List data() { + List list = new ArrayList(); + for (int i = 0; i < 10; i++) { + DemoData data = new DemoData(); + data.setString("字符串" + i); + data.setDate(new Date()); + data.setDoubleData(0.56); + list.add(data); + } + return list; + } + @Test public void testc() throws Exception { LOGGER.info("reslut:{}", JSON.toJSONString(new CellReference("B3"))); diff --git a/update.md b/update.md index 5cdab9b..2078a59 100644 --- a/update.md +++ b/update.md @@ -7,6 +7,10 @@ * 新增支持读取批注、超链接、合并单元格 * 如果是`RuntimeException`则不再封装对象 * 新增`CellData`可以获取行列号 +* 新增样式注解 +* 新增合并单元格注解 +* 提升合并策略效率 +* 兼容部分比较特殊的excel # 2.1.4