1. 代码结构
2. 添加依赖
<dependency>
<groupId>net.sf.supercsv</groupId>
<artifactId>super-csv</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
3. 代码示例
User:
@Getter
@Setter
public class User implements Serializable {
private String name;
private Integer age;
private List<String> interests;
private Map<String, Object> map;
}
FileController:
@Controller
public class FileController {
@Autowired
private FileService fileService;
@GetMapping(value = "generateCSV")
public void generateCSV(HttpServletResponse response) throws Exception {
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition", "attachment;filename=user.csv");
fileService.generateCSV(response);
}
}
FileService:
@Service
public class FileServiceImpl implements FileService {
@Override
public void generateCSV(HttpServletResponse response) throws Exception {
Gson gson = new Gson();
ICsvMapWriter csvWriter = new CsvMapWriter(response.getWriter(), CsvPreference.STANDARD_PREFERENCE);
// 获取头部
String[] headers = generateHeadersArray(User.class.getCanonicalName());
csvWriter.writeHeader(headers);
// 模拟数据,这里包含多种数据类型:String、Integer、List、Map
List<User> users = new ArrayList<>();
for (int i = 0; i < 10; i++) {
User user = new User();
user.setAge(i);
user.setName("test" + i);
List<String> interest = new ArrayList<>();
interest.add("swimming");
interest.add("basketball");
user.setInterests(interest);
Map<String, Object> map = new HashMap<>();
map.put("k1", "v" + i);
map.put("k2", i);
user.setMap(map);
users.add(user);
}
// 写入数据
for (User user : users) {
Map<String, Object> map = new LinkedHashMap<>();
for (Field field : user.getClass().getDeclaredFields()) {
field.setAccessible(true);
map.put(field.getName() ,field.getType().equals(Map.class) || field.getType().equals(List.class) ? gson.toJson(field.get(user)) : field.get(user));
}
csvWriter.write(map, headers);
}
csvWriter.close();
}
/**
*
* 通过实体类包名获取class,并通过反射获取class中所有字段名称
*
* @param packageName 实体类包名
* @return
*/
private String[] generateHeadersArray(String packageName) {
Class cls;
String[] resultArr = new String[0];
try {
cls = Class.forName(String.format("%s", packageName));
resultArr = Arrays.stream(cls.getDeclaredFields()).map(Field::getName).toArray(String[]::new);
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return resultArr;
}
}
4. 效果展示
访问地址:http://localhost:8080/generateCSV