Document example
1024 is the best time to write a blog. Don’t say it, don’t say it, I suggest it become a legal holiday.
The official website of Baoshi documents: Baoshi official website
(@宝思Team
Remember to pay me for advertising)
Steps to use the Boucherie certificate
Use abstract classes to abstract the steps of obtaining fields, greatly reducing the amount of code. Save development costs.
The abstract class is at the bottom of the article, you can get it yourself if you need it.
Steps
1. Create reports
2. Configuration parameters
3. Create a data source object (javaBean)
4. Create a DataSet implementation class
5. Add the path to the DataSet implementation class in the com.basksoft.report.core.model.dataset.BeanDataset
configuration file
6. Load custom bean data set
7. Add database report records
Create a report
Right click to create a report file
Configuration parameters
The parameters here are used to obtain data.
Create data source object
You need to define a empty parameter constructor and a constructor with a Boolean parameter, and assign default data to the attribute in this constructor.
The type of the Boolean constructor needs to be a boxed type (the boxed type of boolean is Boolean)
The purpose of adding the Boolean constructor is to obtain the object of default data.
@Data public class AccountStatementVo {<!-- --> //Settlement unit private String clientName; //Billing date ends private Date reconcDeadline; // Converted currency amount currency system private String cyCode; //Amount converted to currency private BigDecimal amt; //Reconciliation method private String reconcMethod; // illustrate private String actstmDesc; // Bank Account private String bankacctName; // statement number private String actstmNo; public AccountStatementVo() {<!-- -->} public AccountStatementVo(Boolean defaultValue) {<!-- --> this.clientName = "Customer Name"; this.reconcDeadline = new Date(); this.cyCode = "CNY"; this.amt = BigDecimal.ZERO; this.reconcMethod = "Test method"; this.actstmDesc = "File Notes"; this.bankacctName = "Bank of China"; this.actstmNo = "HJ23424"; } }
Create DataSet implementation class
Add a DateSet
class and inherit the AbstractBeanDataSet
abstract class
The abstract class needs to specify two generic types. If the return result is a List type, the first generic type is specified as List
, and the second type is specified as T. Otherwise, specify T
@Slf4j public class BillDataset extends AbstractBeanDataSet<BillDocVo,BillDocVo> {<!-- --> @Override protected boolean getReturnDefaultData(BeanContext beanContext) {<!-- --> return false; } @Override public Result<BillDocVo> getDocVo(BeanContext beanContext) {<!-- --> return null; } @Override protected String name() {<!-- --> return ""; } }
Interface that returns List
public class DemoDataSet extends AbstractBeanDataSet<List<BillDetailVo>,BillDataset> {<!-- --> @Override protected boolean getReturnDefaultData(BeanContext beanContext) {<!-- --> return false; } @Override public Result<List<BillDetailVo>> getDocVo(BeanContext beanContext) {<!-- --> return null; } @Override protected String name() {<!-- --> return null; } }
Override three methods in AbstractBeanDataSet
boolean getReturnDefaultData(BeanContext beanContext)
Obtain the parameters defined in the second step through beanContext.getReportParameter("billId")
Returns a boolean value, whether to obtain default data.
In this method, write your own conditions for obtaining default data.
@Override protected boolean getReturnDefaultData(BeanContext beanContext) {<!-- --> Long billId = ParameterUtils.parseLong(beanContext.getReportParameter("billId")); //If the parameter is empty or 0, get the default data if (Objects.isNull(billId) || Objects.equals(billId, 0L)) {<!-- --> return true; } return false; }
Result getDocVo(BeanContext beanContext)
Method to obtain the data source.
In this method, the interface in the fms project is called through http to obtain the data source. (If necessary later, you can configure the fms data source in the report project and obtain data directly from the report project)
The returned data is the data source object created in the third step
Finally, write this interface to obtain the data source in fms and return the required data object
@Override public Result<BillDocVo> getDocVo(BeanContext beanContext) {<!-- --> Long billId = ParameterUtils.parseLong(beanContext.getReportParameter("billId")); String token = (String) beanContext.getReportParameter("token"); //Configure the access address in the FmsUrlConstants constant class String url = FmsUrlConstants.api + FmsUrlConstants.BILL_DOC; if (!StringUtils.hasText(url)) {<!-- --> return null; } // Use the hutool toolkit to send a get request. If the fms write is a post request, then send the post request. HttpResponse httpResponse = HttpRequest.get(url) .form("billId", billId) .header("token", token) .execute(); //Convert the return result type Result<BillDocVo> result = JSONUtil.toBean(httpResponse.body(), new TypeReference<Result<BillDocVo>>() {<!-- --> }, false); return result; }
String name()
Returns the name of the data source object. The name displayed in the report is defined in this method.
@Override protected String name() {<!-- --> return "Bill"; }
Add dataSet class configuration
Load custom bean data set
Multiple data sets can be added
Add database report records
uni_acv_doc (document master table)
uni_acv_docmodel (single proof template table)
one-to-many relationship
Add report data to these two tables
Add the main document table (uni_acv_doc) and set fields according to respective needs.
doccode,tab_code need to be unique
When adding records to the document details template table (uni_acv_docmodel).
Set docid to the id of the main document table (uni_acv_doc),
Set file_id and sys_file_id to the fileId of the template,
Set is_default to 1
Other data is set as required
AbstractBeanDataSet abstract class
The functions of this abstract class: If you want to obtain default data, call the Boolean constructor to create an object with default data. Otherwise get the data obtained from fms. Encapsulate all fields of the data object into a List<Map<String,Object>> object.
package com.yunwuyun.easy.baskreport.dataset; import com.basksoft.report.core.model.dataset.BeanDataset; import com.basksoft.report.core.model.dataset.impl.BeanContext; import com.basksoft.report.core.model.dataset.impl.Field; import com.basksoft.report.core.model.dataset.impl.FieldType; import com.yunwuyun.easy.baskreport.common.Result; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.*; /** * Document abstract class * @param <T> */ @Slf4j public abstract class AbstractBeanDataSet<T,E> extends BeanDataset {<!-- --> protected Class<E> clazz; public AbstractBeanDataSet() {<!-- --> Type genericSuperclass = getClass().getGenericSuperclass(); if (genericSuperclass instanceof ParameterizedType) {<!-- --> ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass; Type[] typeArguments = parameterizedType.getActualTypeArguments(); if (typeArguments.length > 0) {<!-- --> Type typeArgument = typeArguments[1]; if (typeArgument instanceof Class) {<!-- --> this.clazz = (Class<E>) typeArgument; } } } } @SneakyThrows @Override public List<?> getData(BeanContext beanContext) {<!-- --> boolean returnDefaultData = false; returnDefaultData = this.getReturnDefaultData(beanContext); if(returnDefaultData) {<!-- --> return getDefaultData(); } Result<T> result = this.getDocVo(beanContext); if (result == null || result.getCode() != 200) {<!-- --> return Collections.emptyList(); } T t = result.getResult(); List<Map<String,Object>> datas = getDatas(t); return datas; } protected abstract boolean getReturnDefaultData(BeanContext beanContext); private List<Map<String, Object>> getDatas(T t) {<!-- --> List<Map<String,Object>> datas = new ArrayList<>(); if(isListType()) {<!-- --> List<E> list = (List<E>) t; for (E obj: list) {<!-- --> Map<String, Object> dataMap = getDataMap(obj); datas.add(dataMap); } } else {<!-- --> E obj = (E) t; Map<String, Object> data = getDataMap(obj); datas.add(data); } return datas; } /** * Get the map of all field attributes * @param t * @return */ private Map<String, Object> getDataMap(E t) {<!-- --> List<Field> fields = this.getFields(); Map<String, Object> data = new HashMap<>(); for (Field field : fields) {<!-- --> String fieldName = field.getName(); try {<!-- --> java.lang.reflect.Field fieldVo = this.clazz.getDeclaredField(fieldName); fieldVo.setAccessible(true); data.put(field.getName(), fieldVo.get(t)); } catch (Exception e) {<!-- --> // Ignore the exception and continue processing the next field log.error("Dataset error,fieldName:{}, message:{}", fieldName, e.getMessage()); } } return data; } /** * Whether the generic type is a list * @return */ private Boolean isListType() {<!-- --> Type genericSuperclass = getClass().getGenericSuperclass(); if (genericSuperclass instanceof ParameterizedType) {<!-- --> ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass; Type[] typeArguments = parameterizedType.getActualTypeArguments(); if (typeArguments.length > 0) {<!-- --> Type typeArgument = typeArguments[0]; if (typeArgument instanceof ParameterizedType) {<!-- --> return true; } else if (typeArgument instanceof Class) {<!-- --> return false; } } } return false; } /** * Get data by id * @param beanContext * @return */ public abstract Result<T> getDocVo(BeanContext beanContext); @Override public List<String> getDependCells() {<!-- --> List<String> list = new ArrayList<>(); return list; } @Override protected abstract String name(); @Override public List<Field> getFields() {<!-- --> List<Field> fields = new ArrayList<>(); java.lang.reflect.Field[] allFields = this.clazz.getDeclaredFields(); for (java.lang.reflect.Field fieldVo : allFields) {<!-- --> Class<?> type = fieldVo.getType(); String typeName = type.getSimpleName(); Field field = new Field(fieldVo.getName(), FieldType.valueOf(typeName)); fields.add(field); } return fields; } /** * Get default data * @return default data */ private List<Map<String, Object>> getDefaultData() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException {<!-- --> Constructor<E> constructor = this.clazz.getDeclaredConstructor(Boolean.class); E e = constructor.newInstance(true); List<Map<String,Object>> datas = new ArrayList<>(); Map<String,Object> data = new HashMap<>(); java.lang.reflect.Field[] allFields = this.clazz.getDeclaredFields(); for (java.lang.reflect.Field field : allFields) {<!-- --> field.setAccessible(true); data.put(field.getName(), field.get(e)); } datas.add(data); return datas; } }