概念
AWT:Abstract Window Toolkit, 抽象窗口工具包,提供了一套与本地图形界面进行交互的接口
Spring MVC 上传文件 到磁盘
文件上传请求的特征
1、请求方法:POST
2、请求头:enctype="multipart/form-data"
Spring MVC上传应用组成
1、Bean配置
<!-- 会被DispatcherServlet引用 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="104857600" />
<property name="maxInMemorySize" value="4096" />
<property name="defaultEncoding" value="UTF-8"></property>
</bean>
2、编写Controller
@RequestMapping("springUpload")
public String springUpload(HttpServletRequest request) throws IllegalStateException, IOException
{
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
if(multipartResolver.isMultipart(request)) // 是否是表单数据
{
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
Iterator iter=multiRequest.getFileNames();
while(iter.hasNext())
{
MultipartFile file = multiRequest.getFile(iter.next().toString());
if(file != null)
{
String dir = "/images"; // 相对目录
String fullDir = request.getSession().getServletContext().getRealPath(dir); // 绝对目录
String fullPath = fullDir + file.getOriginalFilename(); // 绝对路径
File srcFile = new File(fullPath);
file.transferTo(srcFile);
}
}
}
return "success";
}
Spring boot上传文件到 OSS
application.yml
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
@RequestMapping(value = "/uploadAvatar", method = RequestMethod.POST)
public RestfulResult avatar(@RequestParam("file") MultipartFile file, HttpSession session) throws IOException {
String endpoint = "**.com";
String accessKeyId = "**";
String accessKeySecret = "**";
String bucketName = "**";
String dir = "avatar/";
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
ossClient.putObject(bucketName, dir + file.getOriginalFilename(), file.getInputStream());
ossClient.shutdown();
return new RestfulResult("");
}
图片水印
图片水印应用组成
1、工具类
public class WaterMarkUtils {
private static final String FONT_FAMILY="微软雅黑";
private static final int FONT_STYLE=Font.BOLD;
private static final int FONT_SIZE=24;
private static final float ALPHA=0.7F; // 透明度
private static final int LOGO_WIDTH=100;
// 添加文字水印
public static void generateWithTextMark(File srcFile, String tarPath, String contents) throws Exception{
Image srcImage=ImageIO.read(srcFile);
int width=srcImage.getWidth(null);
int height=srcImage.getHeight(null);
BufferedImage tarBuffImage=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
Graphics2D g=tarBuffImage.createGraphics();
g.drawImage(srcImage, 0, 0, width,height,null);
int strWidth=FONT_SIZE*getTextLength(contents);
int strHeight=FONT_SIZE;
// 水印位置
int x=0,y=0;
g.setFont(new Font(FONT_FAMILY,FONT_STYLE,FONT_SIZE));
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,ALPHA));
g.rotate(Math.toRadians(-30),width/2,height/2); // 旋转图片
while(x < width*1.5){
y = -height/2;
while(y < height*1.5){
g.drawString(contents,x,y);
y += strHeight + 50;
}
x += strWidth + 50; // 水印之间的间隔设为50
}
g.dispose();
JPEGImageEncoder en = JPEGCodec.createJPEGEncoder(new FileOutputStream(tarPath));
en.encode(tarBuffImage);
}
// 添加图片水印
public static void generateWithImageMark(File srcFile, String tarPath,String logoPath) throws Exception{
Image srcImage=ImageIO.read(srcFile);
int width=srcImage.getWidth(null);
int height=srcImage.getHeight(null);
BufferedImage tarBuffImage=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
Graphics2D g=tarBuffImage.createGraphics();
g.drawImage(srcImage, 0, 0, width,height,null);
Image logoImage=ImageIO.read(new File(logoPath));
int logoWidth=LOGO_WIDTH;
int logoHeight=(LOGO_WIDTH*logoImage.getHeight(null))/logoImage.getWidth(null);
int x=width-logoWidth;
int y=height-logoHeight;
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,ALPHA));
g.drawImage(logoImage, x, y, logoWidth, logoHeight, null);
g.dispose();
JPEGImageEncoder en = JPEGCodec.createJPEGEncoder(new FileOutputStream(tarPath));
en.encode(tarBuffImage);
}
// 相当于几个中文
public static int getTextLength(String text){
int length = text.length();
for(int i=0;i<text.length();i++){
String s = String.valueOf(text.charAt(i));
if(s.getBytes().length>1){ // 中文字符
length++;
}
}
length = length%2 == 0?length/2:length/2+1;
return length;
}
}
2、Controller
@RequestMapping("springUpload")
public String springUpload(HttpServletRequest request) throws IllegalStateException, Exception
{
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
if(multipartResolver.isMultipart(request))
{
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
Iterator iter = multiRequest.getFileNames();
while(iter.hasNext())
{
MultipartFile file = multiRequest.getFile(iter.next().toString());
if(file != null)
{
String dir = "/images"; // 相对目录
String fullDir = request.getSession().getServletContext().getRealPath(dir); // 绝对目录
String fileName = file.getOriginalFilename(); // 文件名
String fullPath = fullDir + fileName; // 绝对路径
File srcFile = new File(fullPath);
file.transferTo(srcFile); // 写入添加水印前的图片
String markPath = fullDir + "/mark_" + fileName;
WaterMarkUtils.generateWithTextMark(srcFile, markPath, "文字水印");
}
}
}
return "success";
}
图片缩略
图片缩略应用组成:
1、配置Maven依赖
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId> <!-- 除了thumbnailator,也可以用AWT实现 -->
<version>0.4.8</version>
</dependency>
2、编写工具类
public class ThumbnailUtil {
public static final int WIDTH=100;
public static final int HEIGHT=100;
// 缩略上传的图片
public static void thumbnail(MultipartFile file, String tarPath){
try {
Thumbnails.Builder<? extends InputStream> thumbnail = Thumbnails.of(file.getInputStream());
thumbnail.size(WIDTH, HEIGHT);
thumbnail.toFile(tarPath);
} catch (Exception e) {
e.printStackTrace();
}
}
// 缩略本地的图片
public static void thumbnail(String srcFile, String tarPath){
try {
Thumbnails.Builder<? extends InputStream> thumbnail = Thumbnails.of(new FileInputStream(srcFile));
thumbnail.size(WIDTH, HEIGHT);
thumbnail.toFile(tarPath);
} catch (Exception e) {
e.printStackTrace();
}
}
}
3、编写Controller
@RequestMapping("springUpload")
public String springUpload(HttpServletRequest request) throws Exception
{
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
if(multipartResolver.isMultipart(request))
{
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
Iterator iter = multiRequest.getFileNames();
while(iter.hasNext())
{
MultipartFile file = multiRequest.getFile(iter.next().toString());
if(file != null)
{
String dir = "/images"; // 相对目录
String fullDir = request.getSession().getServletContext().getRealPath(dir); // 绝对目录
String fileName = file.getOriginalFilename(); // 文件名
String fullPath = fullDir + fileName; // 绝对路径
File srcFile = new File(fullPath);
file.transferTo(srcFile); // 写入原图
String markPath = fullDir + "/mark_"+file.getOriginalFilename();
WaterMarkUtils.generateWithTextMark(srcFile, markPath, "文字水印");
String themPath = fullDir + "/thum_"+file.getOriginalFilename();
ThumbnailUtil.thumbnail(file, themPath); // 缩略无水印图
ThumbnailUtil.thumbnail(markPath, fullDir + "/thum_"+file.getOriginalFilename()); // 缩略水印图
}
}
}
return "success";
}
下载
文件下载响应的特征
1、请求方法:GET
2、响应头:content-type="application/force-download" Content-Disposition="attchement;filename=文件名"
Spring MVC下载应用的组成
1、编写Controller
@RequestMapping("/down")
public ResponseEntity<byte[]> download(HttpServletRequest request) throws IOException {
File file = new File("E://123.jpg"); // 指定源文件
InputStream is = new FileInputStream(file);
byte[] body = new byte[is.available()];
is.read(body);
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "attchement;filename=" + file.getName());
HttpStatus statusCode = HttpStatus.OK;
ResponseEntity<byte[]> entity = new ResponseEntity<byte[]>(body, headers, statusCode);
return entity;
}
导入与导出
Excel解析工具
1、Apache POI:Poor Obfuscation Implementation
官网:http://poi.apache.org/index.html
HSSF:Horrible SpreadSheet Format,解析 xls
XSSF:解析 xlsx
SXSSF:低内存占用版的XSSF,不支持公式求值
2、JXL
官网:http://jxl.sourceforge.net/
对比POI:JXL操作简单,POI功能强大,效率更高
概念
Workbook:工作簿,即一个Excel文件
Sheet:列表,即Excel文件里的一个Tab
Cell:单元格
POI 导入导出应用组成
1、配置Maven依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId> <!-- 解析xls -->
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId> <!-- 解析xlsx -->
<version>4.0.0</version>
</dependency>
2、编写工具类
public class ExcelUtils {
// 把本地文件 读取成 Sheet
public static Sheet getSheet(String filePath) throws Exception {
String extension = filePath.lastIndexOf(".") == -1 ? "" : filePath.substring(filePath.lastIndexOf("."));
InputStream is = new FileInputStream(filePath);
if (".xls".equals(extension)) {
POIFSFileSystem fs = new POIFSFileSystem(is);
return new HSSFWorkbook(fs).getSheetAt(0);
} else if (".xlsx".equals(extension) || ".xlsm".equals(extension)) {
return new XSSFWorkbook(is).getSheetAt(0);
} else {
throw new IOException("文件(" + filePath + "),无法识别!");
}
}
// 把Sheet 解析成 二维数组
private static String[][] getData(int startRow, Sheet sheet) {
int rowNum = sheet.getLastRowNum() + 1;
Row row = sheet.getRow(0);
int colNum = row.getPhysicalNumberOfCells();
String[][] content = new String[rowNum - startRow][colNum];
String[] cols = null;
for (int i = startRow; i < rowNum; i++) {
row = sheet.getRow(i);
cols = new String[colNum];
for (int j = 0; j < colNum; j++) {
cols[j] = getCellValue(row.getCell(j));
content[i - startRow][j] = cols[j];
}
}
return content;
}
// 把本地文件 解析成 二维数组
public static String[][] readExcel(String filepath, int startRow) throws Exception {
File file = new File(filepath);
if (!file.exists()) {
throw new IOException("文件" + filepath + "不存在!");
}
Sheet sheet = getSheet(filepath);
String[][] content = getData(startRow, sheet);
return content;
}
// 把输入流 解析到 二维数组
public static String[][] readExcelByInput(InputStream is, String fileName, int startRow) throws Exception {
String extension = fileName.lastIndexOf(".") == -1 ? "" : fileName.substring(fileName.lastIndexOf("."));
Sheet sheet = null;
if (".xls".equals(extension)) {
POIFSFileSystem fs = new POIFSFileSystem(is);
sheet = new HSSFWorkbook(fs).getSheetAt(0);
} else if (".xlsx".equals(extension) || ".xlsm".equals(extension)) {
sheet = new XSSFWorkbook(is).getSheetAt(0);
} else {
throw new IOException("文件(" + fileName + "),无法识别!");
}
String[][] content = getData(startRow, sheet);
return content;
}
// 获取单元格的值
private static String getCellValue(Cell cell) {
Object result = "";
if (cell != null) {
switch (cell.getCellType()) {
case STRING:
result = cell.getStringCellValue();
break;
case NUMERIC:
if (HSSFDateUtil.isCellDateFormatted(cell)) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = cell.getDateCellValue();
result = sdf.format(date);
} else {
DecimalFormat df = new DecimalFormat("#");
result = df.format(cell.getNumericCellValue());
}
break;
case BOOLEAN:
result = cell.getBooleanCellValue();
break;
case FORMULA:
result = cell.getCellFormula();
break;
case ERROR:
result = cell.getErrorCellValue();
break;
case BLANK:
break;
default:
break;
}
}
return result.toString();
}
// 把List 导出成 本地文件,columnNames(表头名称数组),columns (表头对应的列名数组)
@SuppressWarnings("rawtypes")
public static void exportExcelByList(String filePath, List list, String[] columnNames, String[] columns, String sheetName) {
OutputStream fos = null;
try {
fos = new FileOutputStream(filePath);
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet(sheetName);
HSSFCellStyle style = wb.createCellStyle();
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setAlignment(HorizontalAlignment.CENTER);
HSSFRow row = sheet.createRow(0);
for (int i = 0; i < columnNames.length; i++) {
HSSFCell cell = row.createCell(i);
cell.setCellValue(columnNames[i]);
cell.setCellStyle(style);
}
for (int i = 0; i < list.size(); i++) {
Object o = list.get(i);
HSSFRow listRow = sheet.createRow(i + 1);
for (int j = 0; j < columns.length; j++) {
HSSFCell listCell = listRow.createCell(j);
Method m = o.getClass().getMethod("get" + upperStr(columns[j])); // 利用反射机制调用方法
String value = (String) m.invoke(o);
if (value != null) {
listCell.setCellValue(value);
listCell.setCellStyle(style);
} else {
listCell.setCellValue("");
listCell.setCellStyle(style);
}
sheet.autoSizeColumn(j + 1, true);
}
}
wb.write(fos); // 把工作薄写入到输出流
System.out.println("生成excel成功:" + filePath);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 把List 导出成 HTTP响应,columnNames(表头名称数组),columns (表头对应的列名数组)
@SuppressWarnings("rawtypes")
public static void exportExcel(HttpServletResponse response, List list, String[] columnNames, String[] columns, String sheetName, String filename) {
OutputStream fos = null;
try {
response.setCharacterEncoding("UTF-8");
response.reset();
response.setContentType("octets/stream");
response.addHeader("Content-Disposition", "attachment;filename=" + new String((filename).getBytes("UTF-8"), "iso8859-1") + ".xls");
fos = response.getOutputStream();
HSSFWorkbook wb = new HSSFWorkbook(); // 要导出xlsx文件,则使用 XSSFWorkbook
HSSFSheet sheet = wb.createSheet(sheetName);
HSSFCellStyle style = wb.createCellStyle();
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setAlignment(HorizontalAlignment.CENTER);
HSSFRow row = sheet.createRow(0);
for (int i = 0; i < columnNames.length; i++) {
HSSFCell cell = row.createCell(i);
cell.setCellValue(columnNames[i]);
cell.setCellStyle(style);
}
for (int i = 0; i < list.size(); i++) {
HSSFRow listRow = sheet.createRow(i + 1);
Object o = list.get(i);
for (int j = 0; j < columns.length; j++) {
HSSFCell listCell = listRow.createCell(j);
Method m = o.getClass().getMethod("get" + upperStr(columns[j]));
String value = (String) m.invoke(o);
if (value != null) {
listCell.setCellValue(value + "");
listCell.setCellStyle(style);
} else {
listCell.setCellValue("");
listCell.setCellStyle(style);
}
sheet.autoSizeColumn(j + 1, true);
}
}
wb.write(fos);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 首字母转大写
private static String upperStr(String str) {
char[] ch = str.toCharArray();
if (ch[0] >= 'a' && ch[0] <= 'z') {
ch[0] = (char) (ch[0] - 32);
}
return new String(ch);
}
// 海量数据 导出成 HTTP响应
public static void exportBigData(HttpServletResponse response, List list, String[] columnNames, String[] columns, String sheetName, String filename) {
OutputStream os = null;
try {
response.setContentType("application/force-download");
response.setHeader("Content-Disposition", "attachment;filename=" + filename);
os = response.getOutputStream();
SXSSFWorkbook wb = new SXSSFWorkbook(1000);// 内存中保留 1000 条数据,其余写入硬盘
Sheet sheet = wb.createSheet(sheetName);
int excelRow = 0;
Row titleRow = (Row) sheet.createRow(excelRow++);
for (int i = 0; i < columns.length; i++) {
Cell cell = titleRow.createCell(i);
cell.setCellValue(columns[i]);
}
if (list != null && list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
Row contentRow = (Row) sheet.createRow(excelRow++);
List<String> reParam = (List<String>) list.get(i);
for (int j = 0; j < reParam.size(); j++) {
Cell cell = contentRow.createCell(j);
cell.setCellValue(reParam.get(j));
}
}
}
wb.write(os);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (os != null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3、导入Controller
@RequestMapping("importExcel")
@ResponseBody
public Map<String,Object> importExcel(MultipartFile file){
String[][] data = ExcelUtils.readExcelByInput(file.getInputStream(), file.getOriginalFilename(), 1);
...
}
4、导出Controller
@RequestMapping("/exportExcel")
public void exportExcel(HttpServletResponse response) {
List list = null;
String[] columnNames = new String[]{"列名1","列名2","列名3"};
String[] columns = new String[]{"name","phone","age"};
ExcelUtils.exportExcel(response, list, columnNames,columns, "表名", "文件名");
}
阿里云
对象存储 OSS、文件存储 NAS、混合云存储阵列 Hybrid Cloud Storage Array
网友评论