All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ttzero.excel.entity.Sheet Maven / Gradle / Ivy

/*
 * Copyright (c) 2019, [email protected] All Rights Reserved.
 *
 * 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.ttzero.excel.entity;


import org.ttzero.excel.annotation.TopNS;
import org.ttzero.excel.entity.style.Border;
import org.ttzero.excel.entity.style.Fill;
import org.ttzero.excel.entity.style.Font;
import org.ttzero.excel.entity.style.Horizontals;
import org.ttzero.excel.entity.style.NumFmt;
import org.ttzero.excel.entity.style.Styles;
import org.ttzero.excel.entity.style.Verticals;
import org.ttzero.excel.manager.Const;
import org.ttzero.excel.manager.RelManager;
import org.ttzero.excel.processor.IntConversionProcessor;
import org.ttzero.excel.processor.StyleProcessor;
import org.ttzero.excel.reader.Cell;
import org.ttzero.excel.util.DateUtil;
import org.ttzero.excel.util.FileUtil;

import java.awt.Color;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.nio.file.Path;
import java.sql.Timestamp;

import static org.ttzero.excel.entity.IWorksheetWriter.isBigDecimal;
import static org.ttzero.excel.entity.IWorksheetWriter.isBool;
import static org.ttzero.excel.entity.IWorksheetWriter.isChar;
import static org.ttzero.excel.entity.IWorksheetWriter.isDate;
import static org.ttzero.excel.entity.IWorksheetWriter.isDateTime;
import static org.ttzero.excel.entity.IWorksheetWriter.isDouble;
import static org.ttzero.excel.entity.IWorksheetWriter.isFloat;
import static org.ttzero.excel.entity.IWorksheetWriter.isInt;
import static org.ttzero.excel.entity.IWorksheetWriter.isLocalDate;
import static org.ttzero.excel.entity.IWorksheetWriter.isLocalDateTime;
import static org.ttzero.excel.entity.IWorksheetWriter.isLocalTime;
import static org.ttzero.excel.entity.IWorksheetWriter.isLong;
import static org.ttzero.excel.entity.IWorksheetWriter.isShort;
import static org.ttzero.excel.entity.IWorksheetWriter.isString;
import static org.ttzero.excel.entity.IWorksheetWriter.isTime;
import static org.ttzero.excel.manager.Const.ROW_BLOCK_SIZE;

/**
 * Each worksheet corresponds to one or more sheet.xml of physical.
 * When the amount of data exceeds the upper limit of the worksheet,
 * the extra data will be written in the next worksheet page of the
 * current position, with the name of the parent worksheet. After
 * adding "(1,2,3...n)" as the name of the copied sheet, the pagination
 * is automatic without additional settings.
 * 

* Usually worksheetWriter calls the * {@link #nextBlock} method to load a row-block for writing. * When the row-block returns the flag EOF, mean is the current worksheet * finished written, and the next worksheet is written. *

* Extends the existing worksheet to implement a custom data source worksheet. * The data source can be micro-services, Mybatis, JPA or any others. If * the data source returns an array of json objects, please convert to * an object ArrayList or Map ArrayList, the object ArrayList needs to * extends {@link ListSheet}, the Map ArrayList needs to extends * {@link ListMapSheet} and implement the {@link ListSheet#more} method. *

* If other formats cannot be converted to ArrayList, you * need to inherit from the base class {@link Sheet} and implement the * {@link #resetBlockData} and {@link #getHeaderColumns} methods. * * @see ListSheet * @see ListMapSheet * @see ResultSetSheet * @see StatementSheet *

* Created by guanquan.wang on 2017/9/26. */ @TopNS(prefix = {"", "r"}, value = "worksheet", uri = {Const.SCHEMA_MAIN, Const.Relationship.RELATIONSHIP}) public abstract class Sheet implements Cloneable, Storageable { protected Workbook workbook; protected String name; protected Column[] columns; protected WaterMark waterMark; protected RelManager relManager; protected int id; /** * To mark the cell auto-width */ protected int autoSize; /** * The default cell width */ protected double width = 20; /** * The row number */ protected int rows; /** * Mark the cell is hidden */ protected boolean hidden; protected int headStyle; /** * Automatic interlacing color */ protected int autoOdd = -1; /** * Odd row's background color */ protected int oddFill; /** * A copy worksheet flag */ protected boolean copySheet; protected int copyCount; protected RowBlock rowBlock; protected IWorksheetWriter sheetWriter; /** * To mark the header column is ready */ protected boolean headerReady; /** * Close resource on the last copy worksheet */ protected boolean shouldClose = true; public int getId() { return id; } public void setId(int id) { this.id = id; } public void setSheetWriter(IWorksheetWriter sheetWriter) { this.sheetWriter = sheetWriter; } public Sheet() { this(null); } /** * Constructor worksheet * * @param name the worksheet name */ public Sheet(String name) { this.name = name; relManager = new RelManager(); } /** * Constructor worksheet * * @param name the worksheet name * @param columns the header info */ public Sheet(String name, final Column... columns) { this(name, null, columns); } /** * Constructor worksheet * * @param name the worksheet name * @param waterMark the water mark * @param columns the header info */ public Sheet(String name, WaterMark waterMark, final Column... columns) { this.name = name; this.columns = columns; this.waterMark = waterMark; relManager = new RelManager(); } /** * Associated with Worksheet for controlling head style and cache * column data types and conversions */ public static class Column { /** * The key of Map or field name of entry */ public String key; /** * The header name */ public String name; /** * The cell type */ public Class clazz; /** * The string value is shared */ public boolean share = true; /** * 0: standard 1:percentage 2:RMB */ public int type; /** * The int value conversion */ public IntConversionProcessor processor; /** * The style conversion */ public StyleProcessor styleProcessor; /** * The style of cell, -1 if not be setting */ public int cellStyle = -1; /** * The cell width */ public double width; public int o; public Styles styles; /** * Constructor Column * * @param name the column name * @param clazz the cell type */ public Column(String name, Class clazz) { this(name, clazz, true); } /** * Constructor Column * * @param name the column name * @param key field */ public Column(String name, String key) { this(name, key, true); } /** * Constructor Column * * @param name the column name * @param key field * @param clazz the cell type */ public Column(String name, String key, Class clazz) { this(name, key, true); this.clazz = clazz; } /** * Constructor Column * * @param name the column name * @param clazz the cell type * @param processor The int value conversion */ public Column(String name, Class clazz, IntConversionProcessor processor) { this(name, clazz, processor, true); } /** * Constructor Column * * @param name the column name * @param key field * @param processor The int value conversion */ public Column(String name, String key, IntConversionProcessor processor) { this(name, key, processor, true); } /** * Constructor Column * * @param name the column name * @param clazz the cell type * @param share true:shared false:inline string */ public Column(String name, Class clazz, boolean share) { this.name = name; this.clazz = clazz; this.share = share; } /** * Constructor Column * * @param name the column name * @param key filed * @param share true:shared false:inline string */ public Column(String name, String key, boolean share) { this.name = name; this.key = key; this.share = share; } /** * Constructor Column * * @param name the column name * @param clazz the cell type * @param processor The int value conversion * @param share true:shared false:inline string */ public Column(String name, Class clazz, IntConversionProcessor processor, boolean share) { this(name, clazz, share); this.processor = processor; } /** * Constructor Column * * @param name the column name * @param key field * @param clazz type of cell * @param processor The int value conversion */ public Column(String name, String key, Class clazz, IntConversionProcessor processor) { this(name, key, clazz); this.processor = processor; } /** * Constructor Column * * @param name the column name * @param key field * @param processor The int value conversion * @param share true:shared false:inline string */ public Column(String name, String key, IntConversionProcessor processor, boolean share) { this(name, key, share); this.processor = processor; } /** * Constructor Column * * @param name the column name * @param clazz the cell type * @param cellStyle the style of cell */ public Column(String name, Class clazz, int cellStyle) { this(name, clazz, cellStyle, true); } /** * Constructor Column * * @param name the column name * @param key field * @param cellStyle the style of cell */ public Column(String name, String key, int cellStyle) { this(name, key, cellStyle, true); } /** * Constructor Column * * @param name the column name * @param clazz the cell type * @param cellStyle the style of cell * @param share true:shared false:inline string */ public Column(String name, Class clazz, int cellStyle, boolean share) { this(name, clazz, share); this.cellStyle = cellStyle; } /** * Constructor Column * * @param name the column name * @param key field * @param cellStyle the style of cell * @param share true:shared false:inline string */ public Column(String name, String key, int cellStyle, boolean share) { this(name, key, share); this.cellStyle = cellStyle; } /** * Setting the cell's width * * @param width the width value * @return the {@link Sheet.Column} */ public Column setWidth(double width) { if (width < 0.00000001) { throw new ExcelWriteException("Width " + width + " less than 0."); } this.width = width; return this; } /** * Setting the cell is shared * * @return true:shared false:inline string */ public boolean isShare() { return share; } /** * Setting the cell type * * @param type the cell type * @return the {@link Sheet.Column} */ public Column setType(int type) { this.type = type; return this; } /** * Returns the column name * * @return the column name */ public String getName() { return name; } /** * Setting the column name * * @param name the column name * @return the {@link Sheet.Column} */ public Column setName(String name) { this.name = name; return this; } /** * Returns the cell type * * @return the cell type */ public Class getClazz() { return clazz; } /** * Setting the cell type * * @param clazz the cell type * @return the {@link Sheet.Column} */ public Column setClazz(Class clazz) { this.clazz = clazz; return this; } /** * Setting the int value conversion * * @param processor The int value conversion * @return the {@link Sheet.Column} */ public Column setProcessor(IntConversionProcessor processor) { this.processor = processor; return this; } /** * Setting the style conversion * * @param styleProcessor The style conversion * @return the {@link Sheet.Column} */ public Column setStyleProcessor(StyleProcessor styleProcessor) { this.styleProcessor = styleProcessor; return this; } /** * Returns the width of cell * * @return the cell width */ public double getWidth() { return width; } /** * Setting the cell's style * * @param cellStyle the styles value * @return the {@link Sheet.Column} */ public Column setCellStyle(int cellStyle) { this.cellStyle = cellStyle; return this; } /** * Returns the default horizontal style * the Date, Character, Bool has center value, the * Numeric has right value, otherwise left value * * @return the horizontal value */ int defaultHorizontal() { int horizontal; if (isDate(clazz) || isDateTime(clazz) || isLocalDate(clazz) || isLocalDateTime(clazz) || isTime(clazz) || isLocalTime(clazz) || isChar(clazz) || isBool(clazz)) { horizontal = Horizontals.CENTER; } else if (isInt(clazz) || isLong(clazz) || isFloat(clazz) || isDouble(clazz) || isBigDecimal(clazz)) { horizontal = Horizontals.RIGHT; } else { horizontal = Horizontals.LEFT; } return horizontal; } /** * Setting the cell styles * * @param font the font * @return the {@link Sheet.Column} */ public Column setCellStyle(Font font) { this.cellStyle = styles.of( (font != null ? styles.addFont(font) : 0) | Verticals.CENTER | defaultHorizontal()); return this; } /** * Setting the cell styles * * @param font the font * @param horizontal the horizontal style * @return the {@link Sheet.Column} */ public Column setCellStyle(Font font, int horizontal) { this.cellStyle = styles.of( (font != null ? styles.addFont(font) : 0) | Verticals.CENTER | horizontal); return this; } /** * Setting the cell styles * * @param font the font * @param border the border style * @return the {@link Sheet.Column} */ public Column setCellStyle(Font font, Border border) { this.cellStyle = styles.of( (font != null ? styles.addFont(font) : 0) | (border != null ? styles.addBorder(border) : 0) | Verticals.CENTER | defaultHorizontal()); return this; } /** * Setting the cell styles * * @param font the font * @param border the border style * @param horizontal the horizontal style * @return the {@link Sheet.Column} */ public Column setCellStyle(Font font, Border border, int horizontal) { this.cellStyle = styles.of( (font != null ? styles.addFont(font) : 0) | (border != null ? styles.addBorder(border) : 0) | Verticals.CENTER | horizontal); return this; } /** * Setting the cell styles * * @param font the font * @param fill the fill style * @param border the border style * @return the {@link Sheet.Column} */ public Column setCellStyle(Font font, Fill fill, Border border) { this.cellStyle = styles.of( (font != null ? styles.addFont(font) : 0) | (fill != null ? styles.addFill(fill) : 0) | (border != null ? styles.addBorder(border) : 0) | Verticals.CENTER | defaultHorizontal()); return this; } /** * Setting the cell styles * * @param font the font * @param fill the fill style * @param border the border style * @param horizontal the horizontal style * @return the {@link Sheet.Column} */ public Column setCellStyle(Font font, Fill fill, Border border, int horizontal) { this.cellStyle = styles.of( (font != null ? styles.addFont(font) : 0) | (fill != null ? styles.addFill(fill) : 0) | (border != null ? styles.addBorder(border) : 0) | Verticals.CENTER | horizontal); return this; } /** * Setting the cell styles * * @param font the font * @param fill the fill style * @param border the border style * @param vertical the vertical style * @param horizontal the horizontal style * @return the {@link Sheet.Column} */ public Column setCellStyle(Font font, Fill fill, Border border, int vertical, int horizontal) { this.cellStyle = styles.of( (font != null ? styles.addFont(font) : 0) | (fill != null ? styles.addFill(fill) : 0) | (border != null ? styles.addBorder(border) : 0) | vertical | horizontal); return this; } /** * Setting the cell styles * * @param numFmt the number format * @param font the font * @param fill the fill style * @param border the border style * @param vertical the vertical style * @param horizontal the horizontal style * @return the {@link Sheet.Column} */ public Column setCellStyle(NumFmt numFmt, Font font, Fill fill, Border border, int vertical, int horizontal) { this.cellStyle = styles.of( (numFmt != null ? styles.addNumFmt(numFmt) : 0) | (font != null ? styles.addFont(font) : 0) | (fill != null ? styles.addFill(fill) : 0) | (border != null ? styles.addBorder(border) : 0) | vertical | horizontal); return this; } /** * Setting cell string value is shared * Shared is only valid for strings, and the converted cell type * is also valid for strings. * * @param share true:shared false:inline string * @return the {@link Sheet.Column} */ public Column setShare(boolean share) { this.share = share; return this; } private static final NumFmt ip = new NumFmt("0%_);[Red]\\(0%\\)") // 整数百分比 , ir = new NumFmt("¥0_);[Red]\\(¥0\\)") // 整数人民币 , fp = new NumFmt("0.00%_);[Red]\\(0.00%\\)") // 小数百分比 , fr = new NumFmt("¥0.00_);[Red]\\(¥0.00\\)") // 小数人民币 , tm = new NumFmt("hh:mm:ss") // 时分秒 ; /** * Returns default style based on cell type * * @param clazz the cell type * @return the styles value */ public int getCellStyle(Class clazz) { int style; if (isString(clazz)) { style = Styles.defaultStringBorderStyle(); } else if (isDate(clazz) || isLocalDate(clazz)) { style = Styles.defaultDateBorderStyle(); } else if (isDateTime(clazz) || isLocalDateTime(clazz)) { style = Styles.defaultTimestampBorderStyle(); } else if (isBool(clazz) || isChar(clazz)) { style = Styles.clearHorizontal(Styles.defaultStringBorderStyle()) | Horizontals.CENTER; } else if (isInt(clazz) || isLong(clazz)) { style = Styles.defaultIntBorderStyle(); switch (type) { case Const.ColumnType.NORMAL: // 正常显示数字 break; case Const.ColumnType.PARENTAGE: // 百分比显示 style = Styles.clearNumfmt(style) | styles.addNumFmt(ip); break; case Const.ColumnType.RMB: // 显示人民币 style = Styles.clearNumfmt(style) | styles.addNumFmt(ir); break; default: } } else if (isFloat(clazz) || isDouble(clazz) || isBigDecimal(clazz)) { style = Styles.defaultDoubleBorderStyle(); switch (type) { case Const.ColumnType.NORMAL: // 正常显示数字 break; case Const.ColumnType.PARENTAGE: // 百分比显示 style = Styles.clearNumfmt(style) | styles.addNumFmt(fp); break; case Const.ColumnType.RMB: // 显示人民币 style = Styles.clearNumfmt(style) | styles.addNumFmt(fr); break; default: } } else if (isTime(clazz) || isLocalTime(clazz)) { style = Styles.clearNumfmt(Styles.defaultDateBorderStyle()) | styles.addNumFmt(tm); } else { style = 0; // Auto-style } return style; } /** * Setting the cell styles * * @return the styles value */ public int getCellStyle() { if (cellStyle != -1) { return cellStyle; } return cellStyle = getCellStyle(clazz); } } /** * Returns workbook * * @return the {@link Workbook} */ public Workbook getWorkbook() { return workbook; } /** * Setting the workbook * * @param workbook the {@link Workbook} * @return the {@link Sheet} */ public Sheet setWorkbook(Workbook workbook) { this.workbook = workbook; if (columns != null) { for (int i = 0; i < columns.length; i++) { columns[i].styles = workbook.getStyles(); } } return this; } /** * Output the export detail info * * @param code the message code in message properties file */ public void what(String code) { workbook.what(code); } /** * Output export detail info * * @param code the message code in message properties file * @param args the placeholder values */ public void what(String code, String... args) { workbook.what(code, args); } /** * Returns shared string * * @return the {@link SharedStrings} */ public SharedStrings getSst() { return workbook.getSst(); } /** * Return the cell default width * * @return the width value */ public double getDefaultWidth() { return width; } /** * Setting auto resize cell's width * * @return the {@link Sheet} */ public Sheet autoSize() { this.autoSize = 1; return this; } /** * Setting fix column width * * @return the {@link Sheet} */ public Sheet fixSize() { this.autoSize = 2; return this; } /** * Setting fix column width * * @param width the column width * @return the {@link Sheet} */ public Sheet fixSize(double width) { this.autoSize = 2; this.width = width; if (headerReady) { for (Column hc : columns) { hc.setWidth(width); } } return this; } /** * Returns the re-size setting * * @return 1: auto-size 2:fix-size */ public int getAutoSize() { return autoSize; } /** * Test is auto size column width * * @return true if auto-size */ public boolean isAutoSize() { return autoSize == 1; } /** * Cancel the odd row's fill style * * @return the {@link Sheet} */ public Sheet cancelOddStyle() { this.autoOdd = 1; return this; } public int getAutoOdd() { return autoOdd; } public void setAutoOdd(int autoOdd) { this.autoOdd = autoOdd; } /** * Setting the odd row's fill style * * @param fill the fill style * @return the {@link Sheet} */ public Sheet setOddFill(Fill fill) { this.oddFill = workbook.getStyles().addFill(fill); return this; } /** * Returns the worksheet name * * @return the worksheet name */ public String getName() { return name; } /** * Setting the worksheet name * * @param name the worksheet name * @return the {@link Sheet} */ public Sheet setName(String name) { this.name = name; return this; } /** * Returns the header column info *

* The copy sheet will use the parent worksheet header information. * * @return array of column */ public Column[] getHeaderColumns() { if (!headerReady) { if (columns == null) { columns = new Column[0]; } headerReady = true; } return columns; } /** * Setting the header rows's columns * * @param columns the header row's columns * @return the {@link Sheet} */ public Sheet setColumns(final Column[] columns) { this.columns = columns.clone(); for (int i = 0; i < columns.length; i++) { columns[i].styles = workbook.getStyles(); } return this; } /** * Returns the {@link WaterMark} * * @return the {@link WaterMark} * @see WaterMark */ public WaterMark getWaterMark() { return waterMark; } /** * Setting the {@link WaterMark} * * @param waterMark the {@link WaterMark} * @return the {@link Sheet} */ public Sheet setWaterMark(WaterMark waterMark) { this.waterMark = waterMark; return this; } /** * Returns the worksheet is hidden * * @return true: hidden, false: not hidden */ public boolean isHidden() { return hidden; } /** * Setting the worksheet status * * @return the {@link Sheet} */ public Sheet hidden() { this.hidden = true; return this; } /** * abstract method close * * @throws IOException if I/O error occur */ public void close() throws IOException { if (sheetWriter != null) { sheetWriter.close(); } } /** * Write worksheet data to path * * @param path the storage path * @throws IOException if I/O error occur */ @Override public void writeTo(Path path) throws IOException { if (sheetWriter == null) { throw new ExcelWriteException("Worksheet writer is not instanced."); } if (!copySheet) { paging(); } if (!headerReady) { getHeaderColumns(); } if (rowBlock == null) { rowBlock = new RowBlock(getRowBlockSize()); } else rowBlock.reopen(); sheetWriter.writeTo(path); } /** * Split worksheet data */ protected void paging() { } /** * Add relationship * * @param rel Relationship * @return worksheet */ public Sheet addRel(Relationship rel) { relManager.add(rel); return this; } public Relationship find(String key) { return relManager.likeByTarget(key); } public String getFileName() { return "sheet" + id + Const.Suffix.XML; } /** * Setting the header column styles * * @param font the font * @param fill the fill style * @param border the border style * @return the {@link Sheet} */ public Sheet setHeadStyle(Font font, Fill fill, Border border) { return setHeadStyle(null, font, fill, border, Verticals.CENTER, Horizontals.CENTER); } /** * Setting the header column styles * * @param font the font * @param fill the fill style * @param border the border style * @param vertical the vertical style * @param horizontal the horizontal style * @return the {@link Sheet} */ public Sheet setHeadStyle(Font font, Fill fill, Border border, int vertical, int horizontal) { return setHeadStyle(null, font, fill, border, vertical, horizontal); } /** * Setting the header column styles * * @param numFmt the number format * @param font the font * @param fill the fill style * @param border the border style * @param vertical the vertical style * @param horizontal the horizontal style * @return the {@link Sheet} */ public Sheet setHeadStyle(NumFmt numFmt, Font font, Fill fill, Border border, int vertical, int horizontal) { Styles styles = workbook.getStyles(); headStyle = styles.of( (numFmt != null ? styles.addNumFmt(numFmt) : 0) | (font != null ? styles.addFont(font) : 0) | (fill != null ? styles.addFill(fill) : 0) | (border != null ? styles.addBorder(border) : 0) | vertical | horizontal); return this; } /** * Setting the header cell styles * * @param style the styles value * @return the {@link Sheet} */ public Sheet setHeadStyle(int style) { headStyle = style; return this; } public int defaultHeadStyle() { if (headStyle == 0) { Styles styles = workbook.getStyles(); Font font = new Font(workbook.getI18N().getOrElse("local-font-family", "Arial") , 11, Font.Style.bold, Color.white); headStyle = styles.of(styles.addFont(font) | styles.addFill(Fill.parse("solid #666699")) | styles.addBorder(Border.parse("thin black")) | Verticals.CENTER | Horizontals.CENTER); } return headStyle; } protected static boolean nonOrIntDefault(int style) { return style == -1 || style == Styles.defaultIntBorderStyle() || style == Styles.defaultIntStyle(); } /** * Returns total rows in this worksheet * * @return -1 if unknown or uncertain */ public int size() { return -1; } /** * Returns a row-block. The row-block is content by 32 rows * * @return a row-block */ public RowBlock nextBlock() { // clear first rowBlock.clear(); resetBlockData(); return rowBlock.flip(); } /** * The worksheet is written by units of row-block. The default size * of a row-block is 32, which means that 32 rows of data are * written at a time. If the data is not enough, the {@code more()} * method will be called to get more data. * * @return the row-block size */ public int getRowBlockSize() { return ROW_BLOCK_SIZE; } /** * Write some final info * * @param workSheetPath the worksheet path * @throws IOException if I/O error occur */ public void afterSheetAccess(Path workSheetPath) throws IOException { // relationship relManager.write(workSheetPath, getFileName()); // others ... } /** * Int value conversion to others * * @param cell the cell * @param n the cell value * @param hc the header column */ protected void conversion(Cell cell, int n, Column hc) { Object e = hc.processor.conversion(n); if (e != null) { Class clazz = e.getClass(); if (isInt(clazz)) { if (isChar(clazz)) { cell.setCv((Character) e); } else if (isShort(clazz)) { cell.setNv((Short) e); } else { cell.setNv((Integer) e); } cell.xf = getStyleIndex(hc, e); } else { setCellValue(cell, e, hc, clazz); int style = hc.getCellStyle(clazz); cell.xf = getStyleIndex(hc, n, style); } } else { cell.setBlank(); cell.xf = getStyleIndex(hc, null); } } /** * Setting cell value and cell styles * * @param cell the cell * @param e the cell value * @param hc the header column */ protected void setCellValueAndStyle(Cell cell, Object e, Column hc) { setCellValue(cell, e, hc, hc.getClazz()); if (hc.processor == null) { cell.xf = getStyleIndex(hc, e); } } /** * Setting cell value * * @param cell the cell * @param e the cell value * @param hc the header column * @param clazz the cell value type */ protected void setCellValue(Cell cell, Object e, Column hc, Class clazz) { if (e == null) { setNullValue(cell, hc); return; } boolean hasIntProcessor = hc.processor != null; if (isString(clazz)) { cell.setSv(e.toString()); } else if (isDate(clazz)) { cell.setAv(DateUtil.toDateValue((java.util.Date) e)); } else if (isDateTime(clazz)) { cell.setIv(DateUtil.toDateTimeValue((Timestamp) e)); } else if (isChar(clazz)) { Character c = (Character) e; if (hasIntProcessor) conversion(cell, c, hc); else cell.setCv(c); } else if (isShort(clazz)) { Short t = (Short) e; if (hasIntProcessor) conversion(cell, t, hc); else cell.setNv(t); } else if (isInt(clazz)) { Integer n = (Integer) e; if (hasIntProcessor) conversion(cell, n, hc); else cell.setNv(n); } else if (isLong(clazz)) { cell.setLv((Long) e); } else if (isFloat(clazz)) { cell.setDv((Float) e); } else if (isDouble(clazz)) { cell.setDv((Double) e); } else if (isBool(clazz)) { cell.setBv((Boolean) e); } else if (isBigDecimal(clazz)) { cell.setMv((BigDecimal) e); } else if (isLocalDate(clazz)) { cell.setAv(DateUtil.toDateValue((java.time.LocalDate) e)); } else if (isLocalDateTime(clazz)) { cell.setIv(DateUtil.toDateTimeValue((java.time.LocalDateTime) e)); } else if (isTime(clazz)) { cell.setTv(DateUtil.toTimeValue((java.sql.Time) e)); } else if (isLocalTime(clazz)) { cell.setTv(DateUtil.toTimeValue((java.time.LocalTime) e)); } else { cell.setSv(e.toString()); } } /** * Setting cell value as null * * @param cell the cell * @param hc the header column */ protected void setNullValue(Cell cell, Column hc) { boolean hasIntProcessor = hc.processor != null; if (hasIntProcessor) { conversion(cell, 0, hc); } else cell.setBlank(); } /** * Returns the cell style index * * @param hc the header column * @param o the cell value * @param style the default style * @return the style index in xf */ private int getStyleIndex(Column hc, Object o, int style) { // Interlaced discoloration if (autoOdd == 0 && isOdd() && !Styles.hasFill(style)) { style |= oddFill; } int styleIndex = hc.styles.of(style); if (hc.styleProcessor != null) { style = hc.styleProcessor.build(o, style, hc.styles); styleIndex = hc.styles.of(style); } return styleIndex; } /** * Returns the cell style index * * @param hc the header column * @param o the cell value * @return the style index in xf */ protected int getStyleIndex(Column hc, Object o) { int style = hc.getCellStyle(); return getStyleIndex(hc, o, style); } /** * Check the odd rows * * @return true if odd rows */ protected boolean isOdd() { return (rows & 1) == 1; } /** * Returns the copy worksheet name * * @return the name */ protected String getCopySheetName() { int sub = copyCount; String _name = name; // reset name int i = name.lastIndexOf('('); if (i > 0) { int fs = Integer.parseInt(name.substring(i + 1, name.lastIndexOf(')'))); _name = name.substring(0, name.charAt(i - 1) == ' ' ? i - 1 : i); if (++fs > sub) sub = fs; } return _name + " (" + (sub) + ")"; } @Override public Sheet clone() { Sheet copy = null; try { copy = (Sheet) super.clone(); } catch (CloneNotSupportedException e) { ObjectOutputStream oos = null; ObjectInputStream ois = null; try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(bos); oos.writeObject(this); ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray())); copy = (Sheet) ois.readObject(); } catch (IOException | ClassNotFoundException e1) { try { copy = getClass().getConstructor().newInstance(); } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e2) { e2.printStackTrace(); } } finally { FileUtil.close(oos); FileUtil.close(ois); } } if (copy != null) { copy.copyCount = ++copyCount; copy.name = getCopySheetName(); copy.relManager = relManager.deepClone(); copy.sheetWriter = sheetWriter.clone().setWorksheet(copy); copy.copySheet = true; copy.rows = 0; } return copy; } /** * Check the limit of columns */ public void checkColumnLimit() { int a = columns.length , b = sheetWriter.getColumnLimit(); if (a > b) { throw new TooManyColumnsException(a, b); } } /** * Check the header information is exist * * @return true if exist */ public boolean hasHeaderColumns() { return columns != null && columns.length > 0; } /** * Int conversion to column string number * The max column on sheet is 16_384 *

* int | column number * -------|--------- * 1 | A * 10 | J * 26 | Z * 27 | AA * 28 | AB * 53 | BA * 16_384 | XFD */ private ThreadLocal cache = ThreadLocal.withInitial(() -> new char[][]{{65}, {65, 65}, {65, 65, 65}}); public char[] int2Col(int n) { char[][] cache_col = cache.get(); char[] c; char A = 'A'; if (n <= 26) { c = cache_col[0]; c[0] = (char) (n - 1 + A); } else if (n <= 702) { int t = n / 26, w = n % 26; if (w == 0) { t--; w = 26; } c = cache_col[1]; c[0] = (char) (t - 1 + A); c[1] = (char) (w - 1 + A); } else { int tt = n / 26, t = tt / 26, w = n % 26, m = tt % 26; if (w == 0) { m--; w = 26; } if (m <= 0) { t--; m += 26; } c = cache_col[2]; c[0] = (char) (t - 1 + A); c[1] = (char) (m - 1 + A); c[2] = (char) (w - 1 + A); } return c; } ////////////////////////////Abstract function\\\\\\\\\\\\\\\\\\\\\\\\\\\ /** * Each row-block is multiplexed and will be called to reset * the data when a row-block is completely written. * Call the {@link #getRowBlockSize()} method to get * the row-block size, call the {@link #setCellValueAndStyle(Cell, Object, Column)} * method to set value and styles. */ protected abstract void resetBlockData(); }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy