公式のeasyexcelドキュメントでは、コンテンツのヘッダーセル形式とセル形式を設定できます。セル形式戦略クラスには2つのコンストラクターがあります。
public HorizontalCellStyleStrategy(WriteCellStyle headWriteCellStyle,
List<WriteCellStyle> contentWriteCellStyleList) {
this.headWriteCellStyle = headWriteCellStyle;
this.contentWriteCellStyleList = contentWriteCellStyleList;
}
public HorizontalCellStyleStrategy(WriteCellStyle headWriteCellStyle, WriteCellStyle contentWriteCellStyle) {
this.headWriteCellStyle = headWriteCellStyle;
contentWriteCellStyleList = new ArrayList<WriteCellStyle>();
contentWriteCellStyleList.add(contentWriteCellStyle);
}
2つの違いは次のとおりです。最初のコンストラクターは、以下のソースコードからわかるように、セル形式パラメーターをコンテンツにセットとして設定します。
HorizontalCellStyleStrategy类中给内容设置单元格格式的代码如下:
@Override
protected void setContentCellStyle(Cell cell, Head head, Integer relativeRowIndex) {
if (contentCellStyleList == null || contentCellStyleList.isEmpty()) {
return;
}
cell.setCellStyle(contentCellStyleList.get(relativeRowIndex % contentCellStyleList.size()));
}
contentCellStyleListは、コンストラクター内のコンテンツセル形式コレクションであることがわかります。このコレクションの機能は、実際にはExcelのスタイルを変更することです。たとえば、2つの異なるスタイルを指定すると、1,3,5がスタイルになります。 、2,4,6別のスタイルで動作します。たとえば、3つの異なるスタイルを指定すると、1,4,7は別のスタイルになり、2,5,8は別のスタイルになり、3,6,9は次のようになります。セルを介したスタイル。コードsetCellStyle(contentCellStyleList.get(relativeRowIndex%contentCellStyleList.size()))が表示されます。
上記のコードを通じて、easyexcelは行のスタイルを設定しますが、つまり同じ行では、異なる列スタイルは同じですが、行の各列は上記のコードsetContentCellStyleメソッドを実行するため、ここで書き換えることができます。 、このメソッドを書き直すことで、セル形式を独自に正確に制御できます。
実装は次のとおりです。
デバッグにより、このメソッドのheadパラメータは、以下のremarkパラメータに示すように、セルに対応するエンティティクラスのパラメータ名、つまりフィールドの名前を取得できることがわかりました。
@ExcelProperty("备注")
private String remark;
フィールドの名前がわかるようになったので、自由に遊ぶことができます。
私の実装の最初のバージョンは、フィールドの名前に特定の文字列を入れてから、別のスタイルを設定することです。たとえば、フィールドの名前がamountで終わる場合、設定したセル形式が実行され、他の人は共通のコンテンツセルフォーマットを実行します。
private static final String AMOUNT = "amount";
@Override
protected void setContentCellStyle(Cell cell, Head head, Integer relativeRowIndex) {
if (head.getFieldName().toLowerCase().endsWith(AMOUNT)) {
Workbook wb = cell.getSheet().getWorkbook();
CellStyle cellStyle = wb.createCellStyle();
Font font = wb.createFont();
font.setFontName("宋体");
font.setFontHeightInPoints((short) 13);
cellStyle.setFont(font);
cellStyle.setAlignment(HorizontalAlignment.RIGHT);
cell.setCellStyle(cellStyle);
}else {
super.setContentCellStyle(cell,head,relativeRowIndex);
}
}
上記の実装の最大の制限の1つは、同じ行にさまざまな形式がある場合、使用するのが特に面倒なことです。したがって、2番目の方法があります。カスタム注釈を使用することです。
フィールドの名前を取得できるので、リフレクションについて考えます。フィールドの名前のクラスを指定する限り、フィールドを取得できます。リフレクションを介してフィールドの注釈を取得し、フィールドのセル形式を設定します。実装コードは次のとおりです。
@Slf4j
public class ExcelStyleAnnotationCellWriteHandler extends HorizontalCellStyleStrategy {
private Class c;
ExcelStyleAnnotationCellWriteHandler(Class c, WriteCellStyle headWriteCellStyle, WriteCellStyle contentWriteCellStyle) {
super(headWriteCellStyle, contentWriteCellStyle);
this.c = c;
}
@Override
protected void setContentCellStyle(Cell cell, Head head, Integer relativeRowIndex) {
try {
Field declaredField = c.getDeclaredField(head.getFieldName());
ExcelStyle annotation = declaredField.getAnnotation(ExcelStyle.class);
if (annotation != null) {
Workbook wb = cell.getSheet().getWorkbook();
CellStyle cellStyle = wb.createCellStyle();
Font font = wb.createFont();
font.setFontName(annotation.fontName());
font.setFontHeightInPoints(annotation.fontHeightInPoints());
cellStyle.setFont(font);
cellStyle.setAlignment(annotation.horizontalAlignment());
cellStyle.setVerticalAlignment(annotation.verticalAlignment());
cell.setCellStyle(cellStyle);
}else {
super.setContentCellStyle(cell,head,relativeRowIndex);
}
} catch (NoSuchFieldException e) {
log.error("ExcelStyleAnnotationCellWriteHandler error{0}",e);
}
}
}
自定义注解如下,写的不全,大家可以自行补充
@Target({ElementType.FIELD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExcelStyle {
String fontName() default "宋体";
short fontHeightInPoints() default 12;
HorizontalAlignment horizontalAlignment() default HorizontalAlignment.LEFT;
VerticalAlignment verticalAlignment() default VerticalAlignment.CENTER;
}
注解使用方式如下
@ExcelProperty("账号")
@ColumnWidth(28)
@ExcelStyle(fontName = "宋体",horizontalAlignment = HorizontalAlignment.LEFT)
private String account;
setContentCellStyleメソッドをオーバーライドすることにより、フィールドの注釈が読み取られ、セルがフォーマットされます。注釈がない場合は、一般的なスタイルが採用されます。
複数行のヘッダーを使用するときに発生する問題の1つ:https://github.com/alibaba/easyexcel/issues/990、自分自身に入らないようにチェックアウトできます