poi的shiftRows方法解释
public void shiftRows(int startRow, int endRow, int n) ;
参数:
startRow – 开始移动的行
endRow – 结束移位的行
n – 要移动的行数
startRow到endRow 的区域内容 移动n行数(正数:向下移,负数:向上移)。
**会越过中途经过的行内容;终点行的单元格如果有值则不会被覆盖;空则赋值;**使用写好的模板,动态的向模板中增加行内容;
例:简单的excel的模板内容为:
测试需求:动态的生成用户信息,并在第5行插入5列;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Date;
/**
* 测试控制器
*
* @author yu
*/
public class TestController {
public static void main(String[] args) throws Exception {
//读取源文件
FileInputStream fis = new FileInputStream("F:/test.xlsx");
XSSFWorkbook workbook = new XSSFWorkbook(fis);
//进行模板的克隆(接下来的操作都是针对克隆后的sheet)
XSSFSheet sheet = workbook.cloneSheet(0);
//模拟获取得到的用户内容
ArrayList<UserInfo> list = new ArrayList<>();
for (int i = 0; i < 5; i++) {
UserInfo userInfo = new UserInfo();
userInfo.setU_id(1L);
userInfo.setLogin_id("12345" + i);
userInfo.setPwd("666888" + i);
userInfo.setName("张1" + i);
userInfo.setName_abbr("Z");
userInfo.setSex("男");
userInfo.setBirthday(new Date());
userInfo.setMobile("12345678911");
list.add(userInfo);
}
//将第5行到最后一行的区域内容 向下移动5位;
sheet.shiftRows(4, sheet.getLastRowNum(), list.size());
//插入新行
for (int i = 0; i < list.size(); i++) {
XSSFRow row = sheet.createRow(4 + i);
row.createCell(0).setCellValue(list.get(i).getLogin_id());
row.createCell(1).setCellValue(list.get(i).getPwd());
row.createCell(2).setCellValue(list.get(i).getName());
row.createCell(3).setCellValue(list.get(i).getName_abbr());
row.createCell(4).setCellValue(list.get(i).getSex());
}
//输出为一个新的Excel
String fileName = "test" + System.currentTimeMillis() + ".xlsx";
FileOutputStream out = new FileOutputStream("F:" + "/" + fileName);
//移除workbook中的模板sheet
workbook.removeSheetAt(0);
//给sheet命名
workbook.setSheetName(2, "数据1");
workbook.write(out);
fis.close();
out.flush();
out.close();
}
}
用户实体类
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 用户信息
* </p>
*
* @author yu
* @since 2022-07-27
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "UserInfo对象", description = "")
public class UserInfo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "用户编号")
private Long u_id;
@ApiModelProperty(value = "账号")
private String login_id;
@JsonIgnore
@ApiModelProperty(value = "密码")
private String pwd;
@ApiModelProperty(value = "姓名")
private String name;
@ApiModelProperty(value = "姓名拼音缩写")
private String name_abbr;
@ApiModelProperty(value = "性别")
private String sex;
@ApiModelProperty(value = "生日")
private Date birthday;
@ApiModelProperty(value = "手机")
private String mobile;
@ApiModelProperty(value = "电话")
private String tel;
@ApiModelProperty(value = "传真")
private String fax;
@ApiModelProperty(value = "邮箱")
private String email;
@ApiModelProperty(value = "地址")
private String address;
@ApiModelProperty(value = "创建日期")
private Date create_time;
@ApiModelProperty(value = "创建人")
private String create_name;
@ApiModelProperty(value = "修改日期")
private Date update_time;
@ApiModelProperty(value = "最后更新人")
private String update_name;
@ApiModelProperty(value = "最后登录日期")
private Date last_login;
@ApiModelProperty(value = "状态true false")
private String is_valid;
@ApiModelProperty(value = "钉钉的open_id")
private String dd_open_id;
@ApiModelProperty(value = "创建人ID")
private Long create_id;
@ApiModelProperty(value = "更新人ID")
private Long update_id;
@ApiModelProperty(value = "删除标识,0:未删除;1:删除;默认为0")
private Integer delete_flag;
@ApiModelProperty(value = "工号")
private String job_no;
@ApiModelProperty(value = "账号开通标识 0:未开通 ,1:已开通 默认为0")
private Integer account_flag;
@ApiModelProperty(value = "所属部门编码")
private String dept_code;
@ApiModelProperty(value = "所属部门")
private String dept_name;
@ApiModelProperty(value = "岗位编码")
private String position_code;
@ApiModelProperty(value = "岗位名称")
private String position_name;
}
测试结果:
第五行的单元测试和剩下的行数内容一起向下移动5行,并插入5行新数据;
第二个测试:将第5行和第6行的区域内容向下移动15位,第5行后面的行内容是否会动??
修改部分参数
//将第5行到第6行的区域内容 向下移动15位;
sheet.shiftRows(4, 5, 15);
//插入新行
for (int i = 0; i < 2; i++) {
XSSFRow row = sheet.createRow(4 + i);
row.createCell(0).setCellValue(list.get(i).getLogin_id());
row.createCell(1).setCellValue(list.get(i).getPwd());
row.createCell(2).setCellValue(list.get(i).getName());
row.createCell(3).setCellValue(list.get(i).getName_abbr());
row.createCell(4).setCellValue(list.get(i).getSex());
}
测试结果:
第5行和第6行两行区域内容 会越过后面内容 向下移动15位到20行;第5行后面的行内容不会动;这时会空出2行,添加新数据;
第三个测试:将第5行和第6行的区域内容向上移动3位,看是否会覆盖?
新加一个单元格值
修改部分参数
//将第5行到第6行的区域内容 向上移动3位;
sheet.shiftRows(4, 5, -3);
//插入新行
for (int i = 0; i < 2; i++) {
XSSFRow row = sheet.createRow(4 + i);
row.createCell(0).setCellValue(list.get(i).getLogin_id());
row.createCell(1).setCellValue(list.get(i).getPwd());
row.createCell(2).setCellValue(list.get(i).getName());
row.createCell(3).setCellValue(list.get(i).getName_abbr());
row.createCell(4).setCellValue(list.get(i).getSex());
}
测试结果:
原第5行和第6行两行的区域内容,向上移动3位,因为AB列有值,“单元格测试”没赋值;而H列的内容则显示出来了;
说明不会覆盖已有值;
所用依赖:
<!--poi-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
只进行了简单测试,如果有误,欢迎指正;