前言
最近收到一个生成 PDF 的需求,后端使用的是 springboot 集成 Freemaker 模板引擎,调用第三方接口生成 PDF。
需求细节
PDF 页面表格样式
后端接口入参
java
{
"teamCode":"20240808001A",
"tourTeamList":[
{
"teamName":"AAAA",
"teamInfoList":[
{
"number":"1",
"accumulate":"666.2",
"remark":"YIUY"
},
{
"number":"2",
"accumulate":"666.2",
"remark":"YIUY"
},
{
"number":"3",
"accumulate":"666.2",
"remark":"YIUY"
}
]
}
]
}
如 "前端表格样式" 所示,数据的展示并不是传统的横向展示,而是纵向进行展示,这个时候就需要对接口入参的集合进行特殊处理。
设计思路
根据页面可知,需要将入参的集合左右排列纵向展示:
- 将一个大集合分割成两个小集合,分别表示左排数据和右排数据,要注意分割集合的时候区分集合元素数量是偶数个还是奇数个
- 从下面的图片可知,一行数据下,虽然左三列和右三列相同,但是为了展示数据,一行数据可以看成是一个 Java 实体,这个实体有6个成员变量,表示这一行数据的6列
- 将集合分割成两个小集合后,可知左排集合的第一个元素表示左排三列数据,右排数据的第一个元素表示右排三列数据,所以两个集合的第一个元素组成完整的第一行数据,同理,两个集合的第二个元素组成第二行数据,依此类推。
步骤3的设计代码实现:
(1)左/右两部分table实体
java
import java.io.Serializable;
public class Table implements Serializable {
private static final long serialVersionUID = -1627345966155980666L;
private String data1;
private String data2;
private String data3;
public String getData1() {
return data1;
}
public void setData1(String data1) {
this.data1 = data1;
}
public String getData2() {
return data2;
}
public void setData2(String data2) {
this.data2 = data2;
}
public String getData3() {
return data3;
}
public void setData3(String data3) {
this.data3 = data3;
}
}
(2)表示一整行数据的Java实体
java
import java.io.Serializable;
public class TableForPdf implements Serializable {
private static final long serialVersionUID = -1627345456155980666L;
private String leftData1;
private String leftData2;
private String leftData3;
private String rightData1;
private String rightData2;
private String rightData3;
public String getLeftData1() {
return leftData1;
}
public void setLeftData1(String leftData1) {
this.leftData1 = leftData1;
}
public String getLeftData2() {
return leftData2;
}
public void setLeftData2(String leftData2) {
this.leftData2 = leftData2;
}
public String getLeftData3() {
return leftData3;
}
public void setLeftData3(String leftData3) {
this.leftData3 = leftData3;
}
public String getRightData1() {
return rightData1;
}
public void setRightData1(String rightData1) {
this.rightData1 = rightData1;
}
public String getRightData2() {
return rightData2;
}
public void setRightData2(String rightData2) {
this.rightData2 = rightData2;
}
public String getRightData3() {
return rightData3;
}
public void setRightData3(String rightData3) {
this.rightData3 = rightData3;
}
}
(3)分割及组装
java
/**
*
* @Description:将一个完整的集合分割成两个小集合
* @param list: 返回结果描述
* @return void: 返回值类型
* @throws
*/
public List<TableForPdf> separateList(List<Table> list) {
List<TableForPdf> tableList = new ArrayList<>();
if (list.size() > 0 && list != null) {
List<Table> leftDataList = new ArrayList<>();
List<Table> rightDataList = new ArrayList<>();
int size = list.size();
// 不能被2整除即为奇数个。
if (size % 2 == 1) {
for (int i = 0; i < size; i++) {
if (i < (size / 2 + 1)) {
leftDataList.add(list.get(i));
} else {
rightDataList.add(list.get(i));
}
}
rightDataList.add(new Table());// 这一步是为了保证两个集合元素数量的平衡
} else {
for (int i = 0; i < size; i++) {
if (i < (size / 2)) {
leftDataList.add(list.get(i));
} else {
rightDataList.add(list.get(i));
}
}
}
tableList = createPdfTable(leftDataList, rightDataList);
}
return tableList;
}
/**
*
* @Description:通过分割的两个集合组成table的一行数据
* @param leftDataList
* @param rightDataList
* @return: 返回结果描述
* @return List<TableForPdf>: 返回值类型
* @throws
*/
private List<TableForPdf> createPdfTable(List<Table> leftDataList, List<Table> rightDataList) {
List<TableForPdf> tableList = new ArrayList<>();
for (int i = 0; i < leftDataList.size(); i++) {
for (int j = 0; j < rightDataList.size(); j++) {
if (i == j) {
TableForPdf tableForPdf = new TableForPdf();
tableForPdf.setLeftData1(leftDataList.get(i).getData1());
tableForPdf.setLeftData2(leftDataList.get(i).getData2());
tableForPdf.setLeftData3(leftDataList.get(i).getData3());
tableForPdf.setRightData1(rightDataList.get(j).getData1());
tableForPdf.setRightData2(rightDataList.get(j).getData2());
tableForPdf.setRightData3(rightDataList.get(j).getData3());
tableList.add(tableForPdf);
}
}
}
return tableList;
}
}
代码示例
1、创建接口入参实体
(1)团队人员信息实体
java
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel(value = "团队人员信息", description = "团队人员信息")
public class TourMember implements Serializable {
private static final long serialVersionUID = -1627345966155980666L;
@ApiModelProperty(value = "人员编号")
private String number;
@ApiModelProperty(value = "旅行费用")
private String accumulate;
@ApiModelProperty(value = "注意事项")
private String remark;
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getAccumulate() {
return accumulate;
}
public void setAccumulate(String accumulate) {
this.accumulate = accumulate;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
(2)团队信息实体
java
import java.io.Serializable;
import java.util.List;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel(value = "团队信息", description = "团队信息")
public class TourTeam implements Serializable {
private static final long serialVersionUID = -1632145966155980666L;
@ApiModelProperty(value = "团队名称")
private String teamName;
@ApiModelProperty(value = "团队人员信息")
private List<TourMember> teamInfoList;
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
public List<TourMember> getTeamInfoList() {
return teamInfoList;
}
public void setTeamInfoList(List<TourMember> teamInfoList) {
this.teamInfoList = teamInfoList;
}
}
(3)入参实体
java
import java.io.Serializable;
import java.util.List;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel(value = "接口入参", description = "接口入参")
public class TourInDTO implements Serializable {
private static final long serialVersionUID = -1627345966155980666L;
@ApiModelProperty(value = "团队编码")
private String teamCode;
@ApiModelProperty(value = "团队信息")
private List<TourTeam> tourTeamList;
public String getTeamCode() {
return teamCode;
}
public void setTeamCode(String teamCode) {
this.teamCode = teamCode;
}
public List<TourTeam> getTourTeamList() {
return tourTeamList;
}
public void setTourTeamList(List<TourTeam> tourTeamList) {
this.tourTeamList = tourTeamList;
}
}
2、创建调用生成PDF API入参实体
(1)团队人员 pdf 信息实体
java
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel(value = "团队人员pdf信息", description = "团队人员pdf信息")
public class TourMemberPdf implements Serializable {
private static final long serialVersionUID = -1627345966155980666L;
@ApiModelProperty(value = "左列人员编号")
private String leftNumber;
@ApiModelProperty(value = "左列旅行费用")
private String leftAccumulate;
@ApiModelProperty(value = "左列注意事项")
private String leftRemark;
@ApiModelProperty(value = "右列人员编号")
private String rightNumber;
@ApiModelProperty(value = "右列旅行费用")
private String rightAccumulate;
@ApiModelProperty(value = "右列注意事项")
private String rightRemark;
public String getLeftNumber() {
return leftNumber;
}
public void setLeftNumber(String leftNumber) {
this.leftNumber = leftNumber;
}
public String getLeftAccumulate() {
return leftAccumulate;
}
public void setLeftAccumulate(String leftAccumulate) {
this.leftAccumulate = leftAccumulate;
}
public String getLeftRemark() {
return leftRemark;
}
public void setLeftRemark(String leftRemark) {
this.leftRemark = leftRemark;
}
public String getRightNumber() {
return rightNumber;
}
public void setRightNumber(String rightNumber) {
this.rightNumber = rightNumber;
}
public String getRightAccumulate() {
return rightAccumulate;
}
public void setRightAccumulate(String rightAccumulate) {
this.rightAccumulate = rightAccumulate;
}
public String getRightRemark() {
return rightRemark;
}
public void setRightRemark(String rightRemark) {
this.rightRemark = rightRemark;
}
}
(2)团队信息pdf 实体
java
import java.io.Serializable;
import java.util.List;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel(value = "团队信息pdf", description = "团队信息pdf")
public class TourTeamPdf implements Serializable {
private static final long serialVersionUID = -1632145966155980666L;
@ApiModelProperty(value = "团队名称")
private String teamName;
@ApiModelProperty(value = "团队人员信息")
private List<TourMemberPdf> tableList;
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
public List<TourMemberPdf> getTableList() {
return tableList;
}
public void setTableList(List<TourMemberPdf> tableList) {
this.tableList = tableList;
}
}
(3)pdf接口入参
java
import java.io.Serializable;
import java.util.List;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel(value = "pdf接口入参", description = "pdf接口入参")
public class TourPdfInDTO implements Serializable {
private static final long serialVersionUID = -1627345966155980666L;
@ApiModelProperty(value = "团队编码")
private String teamCode;
@ApiModelProperty(value = "团队信息")
private List<TourTeamPdf> tourTeamList;
public String getTeamCode() {
return teamCode;
}
public void setTeamCode(String teamCode) {
this.teamCode = teamCode;
}
public List<TourTeamPdf> getTourTeamList() {
return tourTeamList;
}
public void setTourTeamList(List<TourTeamPdf> tourTeamList) {
this.tourTeamList = tourTeamList;
}
}