diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/annotation/write/ExcelView.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/annotation/write/ExcelView.java
new file mode 100644
index 000000000..579246f0b
--- /dev/null
+++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/annotation/write/ExcelView.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.fesod.sheet.annotation.write;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.apache.fesod.sheet.write.builder.AbstractExcelWriterParameterBuilder;
+
+/**
+ * Annotation used for indicating view(s) that the property
+ * that is defined by field annotated is part of.
+ *
+ * An example annotation would be:
+ *
+ * @ExcelView(asTypes = BasicView.class)
+ * // Or
+ * @ExcelView(asNames = "BasicView")
+ *
+ * which would specify that field annotated would be included
+ * when processing (writing) Sheet identified by BasicView.class (or its subclass) or
+ * "BasicView".
+ * If multiple View class or string identifiers are included, the field will be part of all of them.
+ *
+ *
+ * @see AbstractExcelWriterParameterBuilder#groups(Class[])
+ * @see AbstractExcelWriterParameterBuilder#groups(String[])
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ExcelView {
+
+ /**
+ * View or views that annotated element is part of. Views are identified
+ * by classes, when a view type is selected, fields annotated with that type
+ * or any of subtypes are included.
+ */
+ Class>[] asTypes() default {};
+
+ /**
+ * View or views that annotated element is part of. Views are identified
+ * by strings.
+ */
+ String[] asNames() default {};
+}
diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/ClassUtils.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/ClassUtils.java
index 2e75fc3e3..dc45e9eca 100644
--- a/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/ClassUtils.java
+++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/ClassUtils.java
@@ -67,6 +67,7 @@
import org.apache.fesod.sheet.metadata.property.NumberFormatProperty;
import org.apache.fesod.sheet.metadata.property.StyleProperty;
import org.apache.fesod.sheet.write.metadata.holder.WriteHolder;
+import org.apache.fesod.sheet.write.view.WriteViewMatcher;
public class ClassUtils {
@@ -346,23 +347,30 @@ private static FieldCache doDeclaredFields(Class> clazz, ConfigurationHolder c
WriteHolder writeHolder = (WriteHolder) configurationHolder;
+ // ignore field by grouping
+ WriteViewMatcher writeViewMatcher = writeHolder.writeViewMatcher();
+ boolean hasViews = (WriteViewMatcher.NOOP != writeViewMatcher);
+ // ignore field by include*/exclude*
boolean needIgnore = !CollectionUtils.isEmpty(writeHolder.excludeColumnFieldNames())
|| !CollectionUtils.isEmpty(writeHolder.excludeColumnIndexes())
|| !CollectionUtils.isEmpty(writeHolder.includeColumnFieldNames())
- || !CollectionUtils.isEmpty(writeHolder.includeColumnIndexes());
+ || !CollectionUtils.isEmpty(writeHolder.includeColumnIndexes())
+ || hasViews;
if (!needIgnore) {
return fieldCache;
}
- // ignore filed
+ // ignore field
Map tempSortedFieldMap = MapUtils.newHashMap();
int index = 0;
for (Map.Entry entry : sortedFieldMap.entrySet()) {
Integer key = entry.getKey();
FieldWrapper field = entry.getValue();
+ boolean isGroupsMismatch = hasViews && !writeViewMatcher.matches(field.getField());
+
// The current field needs to be ignored
- if (writeHolder.ignore(field.getFieldName(), entry.getKey())) {
+ if (isGroupsMismatch || writeHolder.ignore(field.getFieldName(), entry.getKey())) {
ignoreSet.add(field.getFieldName());
indexFieldMap.remove(index);
} else {
@@ -575,6 +583,7 @@ public static class FieldCacheKey {
private Collection excludeColumnIndexes;
private Collection includeColumnFieldNames;
private Collection includeColumnIndexes;
+ private WriteViewMatcher writeViewMatcher;
FieldCacheKey(Class> clazz, ConfigurationHolder configurationHolder) {
this.clazz = clazz;
@@ -584,6 +593,7 @@ public static class FieldCacheKey {
this.excludeColumnIndexes = writeHolder.excludeColumnIndexes();
this.includeColumnFieldNames = writeHolder.includeColumnFieldNames();
this.includeColumnIndexes = writeHolder.includeColumnIndexes();
+ this.writeViewMatcher = writeHolder.writeViewMatcher();
}
}
}
diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/builder/AbstractExcelWriterParameterBuilder.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/builder/AbstractExcelWriterParameterBuilder.java
index 012e5b3ae..47a530f53 100644
--- a/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/builder/AbstractExcelWriterParameterBuilder.java
+++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/builder/AbstractExcelWriterParameterBuilder.java
@@ -27,10 +27,13 @@
import java.util.ArrayList;
import java.util.Collection;
+import org.apache.commons.lang3.ArrayUtils;
import org.apache.fesod.sheet.enums.HeaderMergeStrategy;
import org.apache.fesod.sheet.metadata.AbstractParameterBuilder;
import org.apache.fesod.sheet.write.handler.WriteHandler;
import org.apache.fesod.sheet.write.metadata.WriteBasicParameter;
+import org.apache.fesod.sheet.write.view.ClassBasedViewMatcher;
+import org.apache.fesod.sheet.write.view.NameBasedViewMatcher;
/**
* Build ExcelBuilder
@@ -170,4 +173,34 @@ public T orderByIncludeColumn(Boolean orderByIncludeColumn) {
parameter().setOrderByIncludeColumn(orderByIncludeColumn);
return self();
}
+
+ /**
+ * Only write the fields marked by the following View class identifiers.
+ *
+ * @param types Target View class identifiers
+ * @throws IllegalArgumentException if the types is empty
+ * @return this
+ */
+ public T groups(Class>... types) {
+ if (ArrayUtils.isEmpty(types)) {
+ throw new IllegalArgumentException("Types must not be empty");
+ }
+ parameter().setWriteViewMatcher(new ClassBasedViewMatcher(types));
+ return self();
+ }
+
+ /**
+ * Only write to the fields marked by the following View string identifiers.
+ *
+ * @param names Target View string identifiers
+ * @throws IllegalArgumentException if the names is empty
+ * @return this
+ */
+ public T groups(String... names) {
+ if (ArrayUtils.isEmpty(names)) {
+ throw new IllegalArgumentException("Names must not be empty");
+ }
+ parameter().setWriteViewMatcher(new NameBasedViewMatcher(names));
+ return self();
+ }
}
diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/metadata/WriteBasicParameter.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/metadata/WriteBasicParameter.java
index 5dd959e71..3b134df28 100644
--- a/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/metadata/WriteBasicParameter.java
+++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/metadata/WriteBasicParameter.java
@@ -34,6 +34,7 @@
import org.apache.fesod.sheet.enums.HeaderMergeStrategy;
import org.apache.fesod.sheet.metadata.BasicParameter;
import org.apache.fesod.sheet.write.handler.WriteHandler;
+import org.apache.fesod.sheet.write.view.WriteViewMatcher;
/**
* Write basic parameter
@@ -92,4 +93,9 @@ public class WriteBasicParameter extends BasicParameter {
* Default is {@code false}.
*/
private Boolean orderByIncludeColumn;
+
+ /**
+ * view-based matcher for sheet writing.
+ */
+ private WriteViewMatcher writeViewMatcher;
}
diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/metadata/holder/AbstractWriteHolder.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/metadata/holder/AbstractWriteHolder.java
index 293f18adc..01db93eb2 100644
--- a/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/metadata/holder/AbstractWriteHolder.java
+++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/metadata/holder/AbstractWriteHolder.java
@@ -72,6 +72,7 @@
import org.apache.fesod.sheet.write.style.SheetFreezePaneStrategy;
import org.apache.fesod.sheet.write.style.column.AbstractHeadColumnWidthStyleStrategy;
import org.apache.fesod.sheet.write.style.row.SimpleRowHeightStyleStrategy;
+import org.apache.fesod.sheet.write.view.WriteViewMatcher;
/**
* Write holder configuration
@@ -136,6 +137,11 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
*/
private List> customConverterList;
+ /**
+ * view-based matcher for sheet writing.
+ */
+ private WriteViewMatcher writeViewMatcher;
+
/**
* Write handler
*/
@@ -263,6 +269,16 @@ public AbstractWriteHolder(WriteBasicParameter writeBasicParameter, AbstractWrit
this.includeColumnIndexes = writeBasicParameter.getIncludeColumnIndexes();
}
+ if (writeBasicParameter.getWriteViewMatcher() == null) {
+ if (parentAbstractWriteHolder == null) {
+ this.writeViewMatcher = WriteViewMatcher.NOOP;
+ } else {
+ this.writeViewMatcher = parentAbstractWriteHolder.getWriteViewMatcher();
+ }
+ } else {
+ this.writeViewMatcher = writeBasicParameter.getWriteViewMatcher();
+ }
+
// Initialization property
this.excelWriteHeadProperty = new ExcelWriteHeadProperty(this, getClazz(), getHead());
@@ -599,4 +615,9 @@ public Collection excludeColumnIndexes() {
public Collection excludeColumnFieldNames() {
return getExcludeColumnFieldNames();
}
+
+ @Override
+ public WriteViewMatcher writeViewMatcher() {
+ return getWriteViewMatcher();
+ }
}
diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/metadata/holder/WriteHolder.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/metadata/holder/WriteHolder.java
index 7fdb1bcdc..df13e8ee6 100644
--- a/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/metadata/holder/WriteHolder.java
+++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/metadata/holder/WriteHolder.java
@@ -29,6 +29,7 @@
import org.apache.fesod.sheet.enums.HeaderMergeStrategy;
import org.apache.fesod.sheet.metadata.ConfigurationHolder;
import org.apache.fesod.sheet.write.property.ExcelWriteHeadProperty;
+import org.apache.fesod.sheet.write.view.WriteViewMatcher;
/**
* Get the corresponding Holder
@@ -115,4 +116,9 @@ public interface WriteHolder extends ConfigurationHolder {
* @return
*/
Collection excludeColumnFieldNames();
+
+ /**
+ * view-based matcher for sheet writing.
+ */
+ WriteViewMatcher writeViewMatcher();
}
diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/view/ClassBasedViewMatcher.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/view/ClassBasedViewMatcher.java
new file mode 100644
index 000000000..6a38a9a53
--- /dev/null
+++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/view/ClassBasedViewMatcher.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.fesod.sheet.write.view;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Optional;
+import lombok.EqualsAndHashCode;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.fesod.sheet.annotation.write.ExcelView;
+
+/**
+ * View matcher that resolves view-based on class
+ * identifiers declared in {@code @ExcelView#asTypes()}.
+ */
+@EqualsAndHashCode
+public class ClassBasedViewMatcher implements WriteViewMatcher {
+
+ private final Collection> expectedGroups;
+
+ public ClassBasedViewMatcher(Class>... expectedGroups) {
+ this(ArrayUtils.isEmpty(expectedGroups) ? Collections.emptyList() : Arrays.asList(expectedGroups));
+ }
+
+ public ClassBasedViewMatcher(Collection> expectedGroups) {
+ if (CollectionUtils.isEmpty(expectedGroups)) {
+ throw new IllegalArgumentException("Type-based view groups must not be empty");
+ }
+ this.expectedGroups = Collections.unmodifiableCollection(expectedGroups);
+ }
+
+ @Override
+ public boolean matches(Field field) {
+ Class>[] fieldGroups = Optional.ofNullable(field.getAnnotation(ExcelView.class))
+ .map(ExcelView::asTypes)
+ .orElse(new Class>[0]);
+
+ if (ArrayUtils.isEmpty(fieldGroups)) {
+ return false;
+ }
+
+ return Arrays.stream(fieldGroups).anyMatch(fieldGroup -> expectedGroups.stream()
+ .anyMatch(expectedGroup -> expectedGroup.isAssignableFrom(fieldGroup)));
+ }
+}
diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/view/NameBasedViewMatcher.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/view/NameBasedViewMatcher.java
new file mode 100644
index 000000000..d7020e349
--- /dev/null
+++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/view/NameBasedViewMatcher.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.fesod.sheet.write.view;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Optional;
+import lombok.EqualsAndHashCode;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.fesod.sheet.annotation.write.ExcelView;
+
+/**
+ * View matcher that resolves view-based on string
+ * identifiers declared in {@code @ExcelView#asNames()}.
+ */
+@EqualsAndHashCode
+public class NameBasedViewMatcher implements WriteViewMatcher {
+
+ private final Collection expectedGroups;
+
+ public NameBasedViewMatcher(String... expectedGroups) {
+ this(ArrayUtils.isEmpty(expectedGroups) ? Collections.emptyList() : Arrays.asList(expectedGroups));
+ }
+
+ public NameBasedViewMatcher(Collection expectedGroups) {
+ if (CollectionUtils.isEmpty(expectedGroups)) {
+ throw new IllegalArgumentException("Name-based view groups must not be empty");
+ }
+ this.expectedGroups = Collections.unmodifiableCollection(expectedGroups);
+ }
+
+ @Override
+ public boolean matches(Field field) {
+ String[] fieldGroups = Optional.ofNullable(field.getAnnotation(ExcelView.class))
+ .map(ExcelView::asNames)
+ .orElse(new String[0]);
+
+ if (ArrayUtils.isEmpty(fieldGroups)) {
+ return false;
+ }
+
+ return Arrays.stream(fieldGroups).anyMatch(fieldGroup -> expectedGroups.stream()
+ .anyMatch(expectedGroup -> expectedGroup.equals(fieldGroup)));
+ }
+}
diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/view/WriteViewMatcher.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/view/WriteViewMatcher.java
new file mode 100644
index 000000000..e59992fa2
--- /dev/null
+++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/view/WriteViewMatcher.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.fesod.sheet.write.view;
+
+import java.lang.reflect.Field;
+
+/**
+ * Strategy interface for determining whether Sheet writing should
+ * apply view-based matcher and whether a given field belongs to
+ * the active view(s).
+ */
+public interface WriteViewMatcher {
+
+ /**
+ * A noop implementation for {@link WriteViewMatcher}
+ */
+ WriteViewMatcher NOOP = new WriteViewMatcher() {
+ @Override
+ public boolean matches(Field field) {
+ return false;
+ }
+ };
+
+ /**
+ * Returns whether the given field is included in the active view(s)
+ * based on its {@code @ExcelView} annotation.
+ */
+ boolean matches(Field field);
+}
diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/testkit/assertions/ExcelAssertions.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/testkit/assertions/ExcelAssertions.java
index 5c74b3842..a582275da 100644
--- a/fesod-sheet/src/test/java/org/apache/fesod/sheet/testkit/assertions/ExcelAssertions.java
+++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/testkit/assertions/ExcelAssertions.java
@@ -81,6 +81,13 @@ public SheetAssert sheet(int index) {
return workbook().sheet(index);
}
+ /**
+ * Shortcut to assert on a specific sheet by name.
+ */
+ public SheetAssert sheet(String name) {
+ return workbook().sheet(name);
+ }
+
Workbook getWorkbook() {
return workbook;
}
diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/testkit/assertions/WorkbookAssert.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/testkit/assertions/WorkbookAssert.java
index 39019d1a0..e41c2fd0b 100644
--- a/fesod-sheet/src/test/java/org/apache/fesod/sheet/testkit/assertions/WorkbookAssert.java
+++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/testkit/assertions/WorkbookAssert.java
@@ -60,6 +60,19 @@ public SheetAssert sheet(int index) {
return new SheetAssert(sheet, workbook, this);
}
+ /**
+ * Navigates to a sheet by name for further assertions.
+ *
+ * @throws AssertionError if it does not exist
+ */
+ public SheetAssert sheet(String name) {
+ Sheet sheet = workbook.getSheet(name);
+ if (null == sheet) {
+ throw new AssertionError("Sheet name " + name + " does not exist");
+ }
+ return new SheetAssert(sheet, workbook, this);
+ }
+
/**
* Returns to the parent assertion chain.
*/
diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/util/ClassUtilsTest.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/util/ClassUtilsTest.java
index 3db502620..a395cc43a 100644
--- a/fesod-sheet/src/test/java/org/apache/fesod/sheet/util/ClassUtilsTest.java
+++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/util/ClassUtilsTest.java
@@ -30,6 +30,7 @@
import org.apache.fesod.sheet.annotation.ExcelProperty;
import org.apache.fesod.sheet.annotation.format.DateTimeFormat;
import org.apache.fesod.sheet.annotation.format.NumberFormat;
+import org.apache.fesod.sheet.annotation.write.ExcelView;
import org.apache.fesod.sheet.converters.Converter;
import org.apache.fesod.sheet.converters.string.StringStringConverter;
import org.apache.fesod.sheet.enums.CacheLocationEnum;
@@ -43,6 +44,9 @@
import org.apache.fesod.sheet.metadata.property.StyleProperty;
import org.apache.fesod.sheet.testkit.Tags;
import org.apache.fesod.sheet.write.metadata.holder.WriteHolder;
+import org.apache.fesod.sheet.write.view.ClassBasedViewMatcher;
+import org.apache.fesod.sheet.write.view.NameBasedViewMatcher;
+import org.apache.fesod.sheet.write.view.WriteViewMatcher;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
@@ -87,6 +91,18 @@ private static class SimpleEntity {
private Integer age;
}
+ interface BasicView {}
+
+ private static class ViewEntity {
+ @ExcelView(asTypes = BasicView.class)
+ @ExcelProperty("Name")
+ private String name;
+
+ @ExcelView(asNames = "BasicView")
+ @ExcelProperty(value = "Age")
+ private Integer age;
+ }
+
private static class ComplexEntity {
@ExcelProperty(index = 0)
private String id;
@@ -117,6 +133,7 @@ private static class FormatEntity {
@Test
void test_declaredFields_cache_memory() {
Mockito.when(globalConfiguration.getFiledCacheLocation()).thenReturn(CacheLocationEnum.MEMORY);
+ Mockito.when(writeHolder.writeViewMatcher()).thenReturn(WriteViewMatcher.NOOP);
FieldCache cache1 = ClassUtils.declaredFields(SimpleEntity.class, writeHolder);
Assertions.assertNotNull(cache1);
@@ -130,6 +147,7 @@ void test_declaredFields_cache_memory() {
@Test
void test_declaredFields_cache_ThreadLocal() {
Mockito.when(globalConfiguration.getFiledCacheLocation()).thenReturn(CacheLocationEnum.THREAD_LOCAL);
+ Mockito.when(writeHolder.writeViewMatcher()).thenReturn(WriteViewMatcher.NOOP);
FieldCache cache1 = ClassUtils.declaredFields(SimpleEntity.class, writeHolder);
Assertions.assertNotNull(cache1);
@@ -143,6 +161,7 @@ void test_declaredFields_cache_ThreadLocal() {
@Test
void test_declaredFields_non_cache() {
Mockito.when(globalConfiguration.getFiledCacheLocation()).thenReturn(CacheLocationEnum.NONE);
+ Mockito.when(writeHolder.writeViewMatcher()).thenReturn(WriteViewMatcher.NOOP);
FieldCache cache1 = ClassUtils.declaredFields(SimpleEntity.class, writeHolder);
FieldCache cache2 = ClassUtils.declaredFields(SimpleEntity.class, writeHolder);
@@ -154,6 +173,7 @@ void test_declaredFields_non_cache() {
@Test
void test_declaredFields_ordering() {
Mockito.when(globalConfiguration.getFiledCacheLocation()).thenReturn(CacheLocationEnum.NONE);
+ Mockito.when(writeHolder.writeViewMatcher()).thenReturn(WriteViewMatcher.NOOP);
FieldCache fieldCache = ClassUtils.declaredFields(ComplexEntity.class, writeHolder);
Map sortedMap = fieldCache.getSortedFieldMap();
@@ -174,6 +194,7 @@ void test_declaredFields_ordering() {
@Test
void test_declaredFields_ignore() {
Mockito.when(globalConfiguration.getFiledCacheLocation()).thenReturn(CacheLocationEnum.NONE);
+ Mockito.when(writeHolder.writeViewMatcher()).thenReturn(WriteViewMatcher.NOOP);
FieldCache fieldCache = ClassUtils.declaredFields(ComplexEntity.class, writeHolder);
@@ -186,6 +207,7 @@ void test_declaredFields_ignore() {
@Test
void test_declaredFields_WriteHolder_exclude() {
Mockito.when(globalConfiguration.getFiledCacheLocation()).thenReturn(CacheLocationEnum.NONE);
+ Mockito.when(writeHolder.writeViewMatcher()).thenReturn(WriteViewMatcher.NOOP);
Mockito.when(writeHolder.excludeColumnFieldNames()).thenReturn(Collections.singleton("name"));
Mockito.when(writeHolder.ignore(Mockito.anyString(), Mockito.anyInt())).thenReturn(false);
@@ -205,6 +227,7 @@ void test_declaredFields_WriteHolder_exclude() {
@Test
void test_declaredFields_resort() {
Mockito.when(globalConfiguration.getFiledCacheLocation()).thenReturn(CacheLocationEnum.NONE);
+ Mockito.when(writeHolder.writeViewMatcher()).thenReturn(WriteViewMatcher.NOOP);
Mockito.when(writeHolder.orderByIncludeColumn()).thenReturn(true);
List include = Arrays.asList("age", "name");
@@ -224,6 +247,7 @@ void test_declaredFields_resort_byIndex() {
Mockito.when(writeHolder.includeColumnFieldNames()).thenReturn(null);
Mockito.when(writeHolder.includeColumnIndexes()).thenReturn(Arrays.asList(2, 0));
Mockito.when(writeHolder.ignore(Mockito.anyString(), Mockito.anyInt())).thenReturn(false);
+ Mockito.when(writeHolder.writeViewMatcher()).thenReturn(WriteViewMatcher.NOOP);
FieldCache fieldCache = ClassUtils.declaredFields(ComplexEntity.class, writeHolder);
Map sortedMap = fieldCache.getSortedFieldMap();
@@ -237,6 +261,34 @@ void test_declaredFields_resort_byIndex() {
Assertions.assertEquals("id", sortedMap.get(1).getFieldName());
}
+ @Test
+ void test_declaredFields_typed_views_write() {
+ Mockito.when(globalConfiguration.getFiledCacheLocation()).thenReturn(CacheLocationEnum.NONE);
+ Mockito.when(writeHolder.writeViewMatcher())
+ .thenReturn(new ClassBasedViewMatcher(Collections.singleton(BasicView.class)));
+
+ FieldCache fieldCache = ClassUtils.declaredFields(ViewEntity.class, writeHolder);
+
+ Map sortedMap = fieldCache.getSortedFieldMap();
+
+ Assertions.assertEquals(1, sortedMap.size());
+ Assertions.assertEquals("name", sortedMap.get(0).getFieldName());
+ }
+
+ @Test
+ void test_declaredFields_named_views_write() {
+ Mockito.when(globalConfiguration.getFiledCacheLocation()).thenReturn(CacheLocationEnum.NONE);
+ Mockito.when(writeHolder.writeViewMatcher())
+ .thenReturn(new NameBasedViewMatcher(Collections.singleton("BasicView")));
+
+ FieldCache fieldCache = ClassUtils.declaredFields(ViewEntity.class, writeHolder);
+
+ Map sortedMap = fieldCache.getSortedFieldMap();
+
+ Assertions.assertEquals(1, sortedMap.size());
+ Assertions.assertEquals("age", sortedMap.get(0).getFieldName());
+ }
+
@Test
void test_declaredExcelContentProperty() {
Mockito.when(globalConfiguration.getFiledCacheLocation()).thenReturn(CacheLocationEnum.NONE);
diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/view/WriteMixedViewData.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/view/WriteMixedViewData.java
new file mode 100644
index 000000000..f502c5f9a
--- /dev/null
+++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/view/WriteMixedViewData.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.fesod.sheet.view;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.apache.fesod.sheet.annotation.write.ExcelView;
+
+@EqualsAndHashCode
+@Data
+public class WriteMixedViewData {
+
+ @ExcelView(
+ asTypes = {WriteViewStrategy.BaseView.class},
+ asNames = {"base"})
+ private String string1;
+
+ @ExcelView(
+ asTypes = {WriteViewStrategy.GroupA.class},
+ asNames = {"detail", "export"})
+ private String string2;
+
+ @ExcelView(asNames = {"detail"})
+ private String string3;
+
+ private String defaultString;
+}
diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/view/WriteNamedViewsData.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/view/WriteNamedViewsData.java
new file mode 100644
index 000000000..149c1ab77
--- /dev/null
+++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/view/WriteNamedViewsData.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.fesod.sheet.view;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.apache.fesod.sheet.annotation.write.ExcelView;
+
+@EqualsAndHashCode
+@Data
+public class WriteNamedViewsData {
+
+ @ExcelView(asNames = {"base"})
+ private String string1;
+
+ @ExcelView(asNames = {"base", "detail"})
+ private String string2;
+
+ @ExcelView(asNames = {"detail"})
+ private String string3;
+
+ @ExcelView(asNames = {"other"})
+ private String string4;
+}
diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/view/WriteSheetViewTests.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/view/WriteSheetViewTests.java
new file mode 100644
index 000000000..1a2666cb1
--- /dev/null
+++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/view/WriteSheetViewTests.java
@@ -0,0 +1,238 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.fesod.sheet.view;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVParser;
+import org.apache.commons.io.input.BOMInputStream;
+import org.apache.fesod.sheet.FesodSheet;
+import org.apache.fesod.sheet.support.ExcelTypeEnum;
+import org.apache.fesod.sheet.testkit.Tags;
+import org.apache.fesod.sheet.testkit.assertions.ExcelAssertions;
+import org.apache.fesod.sheet.testkit.assertions.RowAssert;
+import org.apache.fesod.sheet.testkit.base.AbstractExcelTest;
+import org.apache.fesod.sheet.testkit.enums.ExcelFormat;
+import org.apache.fesod.sheet.testkit.params.ExcelFormatSource;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+
+/**
+ * Tests for the view-based export grouping feature using {@code @ExcelView}.
+ */
+@Tag(Tags.ROUND_TRIP)
+@Tag(Tags.WRITE)
+class WriteSheetViewTests extends AbstractExcelTest {
+
+ static final String SHEET_NAME = "TestSheetView";
+
+ private void verifyHeaders(File file, ExcelTypeEnum excelType, List expectedHeads) throws Exception {
+ if (excelType == ExcelTypeEnum.CSV) {
+ try (InputStream is = BOMInputStream.builder()
+ .setInputStream(Files.newInputStream(file.toPath()))
+ .get();
+ Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {
+ CSVParser parser = CSVFormat.DEFAULT.withFirstRecordAsHeader().parse(reader);
+
+ Map headerMap = parser.getHeaderMap();
+
+ Assertions.assertNotNull(headerMap, "CSV file is empty");
+
+ String[] headers = headerMap.keySet().toArray(new String[0]);
+ Assertions.assertEquals(expectedHeads.size(), headers.length, "CSV Header count mismatch");
+ for (int i = 0; i < expectedHeads.size(); i++) {
+ Assertions.assertEquals(expectedHeads.get(i), headers[i], "CSV Header text mismatch");
+ }
+ }
+ } else {
+ try (ExcelAssertions ea = ExcelAssertions.assertThat(file)) {
+ RowAssert ra = ea.workbook().hasSheetCount(1).sheet(SHEET_NAME).row(0);
+
+ for (int i = 0; i < expectedHeads.size(); i++) {
+ ra.cell(i).hasStringValue(expectedHeads.get(i));
+ }
+ }
+ }
+ }
+
+ // =========================================================================
+ // Test by Class Type
+ // =========================================================================
+
+ @Nested
+ class ClassBasedViewTests {
+
+ @ParameterizedTest
+ @ExcelFormatSource
+ void testWriteWithBaseAndSubTypes(ExcelFormat format) throws Exception {
+ File file = createTempFile("SheetView", format);
+ List expectedHeads = Arrays.asList("string1", "string2", "string5");
+
+ // Write
+ FesodSheet.write(file)
+ .head(WriteTypedViewsData.class)
+ .excelType(format.toExcelTypeEnum())
+ .groups(WriteViewStrategy.BaseView.class)
+ .sheet(SHEET_NAME)
+ .doWrite(Collections.emptyList());
+
+ // Verify
+ verifyHeaders(file, format.toExcelTypeEnum(), expectedHeads);
+ }
+
+ @ParameterizedTest
+ @ExcelFormatSource
+ void testWriteWithExactViewMatch(ExcelFormat format) throws Exception {
+ File file = createTempFile("SheetView", format);
+ List expectedHeads = Arrays.asList("string2", "string3");
+
+ // Write
+ FesodSheet.write(file)
+ .head(WriteTypedViewsData.class)
+ .excelType(format.toExcelTypeEnum())
+ .groups(WriteViewStrategy.GroupA.class)
+ .sheet(SHEET_NAME)
+ .doWrite(Collections.emptyList());
+
+ // Verify
+ verifyHeaders(file, format.toExcelTypeEnum(), expectedHeads);
+ }
+
+ @ParameterizedTest
+ @ExcelFormatSource
+ void testWriteWithMultipleGroups(ExcelFormat format) throws Exception {
+ File file = createTempFile("SheetView", format);
+ List expectedHeads = Arrays.asList("string2", "string3", "string4");
+
+ // Write
+ FesodSheet.write(file)
+ .head(WriteTypedViewsData.class)
+ .excelType(format.toExcelTypeEnum())
+ .groups(WriteViewStrategy.GroupA.class, WriteViewStrategy.GroupB.class)
+ .sheet(SHEET_NAME)
+ .doWrite(Collections.emptyList());
+
+ // Verify
+ verifyHeaders(file, format.toExcelTypeEnum(), expectedHeads);
+ }
+ }
+
+ // =========================================================================
+ // Test by String Label Type
+ // =========================================================================
+
+ @Nested
+ class StringBasedViewTests {
+
+ @ParameterizedTest
+ @ExcelFormatSource
+ void testWriteWithSingleView(ExcelFormat format) throws Exception {
+ File file = createTempFile("SheetView", format);
+ List expectedHeads = Arrays.asList("string1", "string2");
+
+ // Write
+ FesodSheet.write(file)
+ .head(WriteNamedViewsData.class)
+ .excelType(format.toExcelTypeEnum())
+ .groups("base")
+ .sheet(SHEET_NAME)
+ .doWrite(Collections.emptyList());
+
+ // Verify
+ verifyHeaders(file, format.toExcelTypeEnum(), expectedHeads);
+ }
+
+ @ParameterizedTest
+ @ExcelFormatSource
+ void testWriteWithMultipleViews(ExcelFormat format) throws Exception {
+ File file = createTempFile("SheetView", format);
+ List expectedHeads = Arrays.asList("string1", "string2", "string3");
+
+ // Write
+ FesodSheet.write(file)
+ .head(WriteNamedViewsData.class)
+ .excelType(format.toExcelTypeEnum())
+ .groups("base", "detail")
+ .sheet(SHEET_NAME)
+ .doWrite(Collections.emptyList());
+
+ // Verify
+ verifyHeaders(file, format.toExcelTypeEnum(), expectedHeads);
+ }
+ }
+
+ // =========================================================================
+ // Test for Conflict and Override Strategies, and Default Behavior
+ // =========================================================================
+
+ @Nested
+ class ConflictAndEdgeCaseTests {
+
+ @ParameterizedTest
+ @ExcelFormatSource
+ void testTagOverridesViewWhenCalledLast(ExcelFormat format) throws Exception {
+ // The tags called later should override the previous groups.
+ File file = createTempFile("SheetView", format);
+ List expectedHeads = Arrays.asList("string2", "string3");
+
+ // Write
+ FesodSheet.write(file)
+ .head(WriteMixedViewData.class)
+ .excelType(format.toExcelTypeEnum())
+ .groups(WriteViewStrategy.BaseView.class)
+ // Take effect
+ .groups("detail")
+ .sheet(SHEET_NAME)
+ .doWrite(Collections.emptyList());
+
+ // Verify
+ verifyHeaders(file, format.toExcelTypeEnum(), expectedHeads);
+ }
+
+ @ParameterizedTest
+ @ExcelFormatSource
+ void testWriteWithoutViewApi(ExcelFormat format) throws Exception {
+ // Export all fields marked and unmarked with @ExcelView
+ File file = createTempFile("SheetView", format);
+ List expectedHeads = Arrays.asList("string1", "string2", "string3", "defaultString");
+
+ // Write
+ FesodSheet.write(file)
+ .head(WriteMixedViewData.class)
+ .excelType(format.toExcelTypeEnum())
+ .sheet(SHEET_NAME)
+ .doWrite(Collections.emptyList());
+
+ // Verify
+ verifyHeaders(file, format.toExcelTypeEnum(), expectedHeads);
+ }
+ }
+}
diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/view/WriteTypedViewsData.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/view/WriteTypedViewsData.java
new file mode 100644
index 000000000..0cad2b8a2
--- /dev/null
+++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/view/WriteTypedViewsData.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.fesod.sheet.view;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.apache.fesod.sheet.annotation.write.ExcelView;
+import org.apache.fesod.sheet.view.WriteViewStrategy.BaseView;
+import org.apache.fesod.sheet.view.WriteViewStrategy.ExtendGroupC;
+import org.apache.fesod.sheet.view.WriteViewStrategy.GroupA;
+import org.apache.fesod.sheet.view.WriteViewStrategy.GroupB;
+
+@EqualsAndHashCode
+@Data
+public class WriteTypedViewsData {
+
+ @ExcelView(asTypes = {BaseView.class})
+ private String string1;
+
+ @ExcelView(asTypes = {BaseView.class, GroupA.class})
+ private String string2;
+
+ @ExcelView(asTypes = {GroupA.class, GroupB.class})
+ private String string3;
+
+ @ExcelView(asTypes = {GroupB.class})
+ private String string4;
+
+ @ExcelView(asTypes = {ExtendGroupC.class})
+ private String string5;
+}
diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/view/WriteViewStrategy.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/view/WriteViewStrategy.java
new file mode 100644
index 000000000..a6dd5d924
--- /dev/null
+++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/view/WriteViewStrategy.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.fesod.sheet.view;
+
+public interface WriteViewStrategy {
+
+ interface BaseView {}
+
+ interface GroupA {}
+
+ interface GroupB {}
+
+ interface ExtendGroupC extends BaseView {}
+}
diff --git a/website/docs/sheet/help/annotation.md b/website/docs/sheet/help/annotation.md
index 19287de69..d82761ea3 100644
--- a/website/docs/sheet/help/annotation.md
+++ b/website/docs/sheet/help/annotation.md
@@ -157,3 +157,12 @@ Define a freeze pane for an Excel sheet. The parameters are as follows:
| rowSplit | 0 | Vertical position of freeze pane. |
| leftmostColumn | -1 | Left column visible in right pane. By default, it's equal to `colSplit`. |
| topRow | -1 | Top row visible in bottom pane. By default, it's equal to `rowSplit`. |
+
+### `@ExcelView`
+
+Defines the view(s) that the field belongs to. During spreadsheet writing, only fields whose declared views match the active view will be included. The parameters are as follows:
+
+| Name | Default Value | Description |
+|---------|---------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| asTypes | Empty | View or views that annotated element is part of. Views are identified by classes, when
a view type is selected, fields annotated with that type or any of subtypes are included. |
+| asNames | Empty | View or views that annotated element is part of. Views are identified by strings. |
diff --git a/website/i18n/zh-cn/docusaurus-plugin-content-docs/current/sheet/help/annotation.md b/website/i18n/zh-cn/docusaurus-plugin-content-docs/current/sheet/help/annotation.md
index bcecf7f2b..c72815dda 100644
--- a/website/i18n/zh-cn/docusaurus-plugin-content-docs/current/sheet/help/annotation.md
+++ b/website/i18n/zh-cn/docusaurus-plugin-content-docs/current/sheet/help/annotation.md
@@ -134,3 +134,12 @@ title: '注解'
| rowSplit | 0 | 冻结窗格的垂直位置(即需要冻结的行数) |
| leftmostColumn | -1 | 右侧窗格中可见的最左侧列。默认情况下,该值等于 `colSplit` |
| topRow | -1 | 底部窗格中可见的最顶部行。默认情况下,该值等于 `rowSplit` |
+
+### `@ExcelView`
+
+定义字段所属视图。在执行电子表格写入时,只有与当前视图匹配的字段才会参与写入。具体参数如下:
+
+| 名称 | 默认值 | 描述 |
+|---------|-----|-----------------------------------------------------------------------|
+| asTypes | 空 | 被注解元素所属的一个或多个视图。视图由类进行标识,当选择一个视图类型时,用该类型
或其任何子类型注解的字段都将被包含在当前视图内。 |
+| asNames | 空 | 该注解元素所属的一个或多个视图,视图由字符串进行标识。 |