|
@@ -5,9 +5,11 @@ import com.itextpdf.text.pdf.PdfCopy;
|
|
import com.itextpdf.text.pdf.PdfReader;
|
|
import com.itextpdf.text.pdf.PdfReader;
|
|
import org.apache.commons.lang.StringUtils;
|
|
import org.apache.commons.lang.StringUtils;
|
|
import org.apache.poi.ss.usermodel.ClientAnchor;
|
|
import org.apache.poi.ss.usermodel.ClientAnchor;
|
|
|
|
+import org.apache.poi.ss.usermodel.Picture;
|
|
import org.apache.poi.ss.usermodel.Sheet;
|
|
import org.apache.poi.ss.usermodel.Sheet;
|
|
import org.apache.poi.ss.util.CellRangeAddress;
|
|
import org.apache.poi.ss.util.CellRangeAddress;
|
|
import org.apache.poi.util.Units;
|
|
import org.apache.poi.util.Units;
|
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFPicture;
|
|
import org.springblade.common.utils.CommonUtil;
|
|
import org.springblade.common.utils.CommonUtil;
|
|
import org.springblade.common.vo.DataVO;
|
|
import org.springblade.common.vo.DataVO;
|
|
import org.springblade.core.tool.utils.IoUtil;
|
|
import org.springblade.core.tool.utils.IoUtil;
|
|
@@ -26,12 +28,12 @@ import java.util.zip.ZipOutputStream;
|
|
|
|
|
|
public class FileUtils {
|
|
public class FileUtils {
|
|
|
|
|
|
- public static void batchDownloadFileToZip(List<String> urls, HttpServletResponse response){
|
|
|
|
|
|
+ public static void batchDownloadFileToZip(List<String> urls, HttpServletResponse response) {
|
|
// 设置压缩流:直接写入response,实现边压缩边下载
|
|
// 设置压缩流:直接写入response,实现边压缩边下载
|
|
ZipOutputStream zipos = null;
|
|
ZipOutputStream zipos = null;
|
|
// 循环将文件写入压缩流
|
|
// 循环将文件写入压缩流
|
|
DataOutputStream os = null;
|
|
DataOutputStream os = null;
|
|
- try{
|
|
|
|
|
|
+ try {
|
|
|
|
|
|
// 响应头的设置
|
|
// 响应头的设置
|
|
response.reset();
|
|
response.reset();
|
|
@@ -51,17 +53,17 @@ public class FileUtils {
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
|
|
- if(zipos == null){
|
|
|
|
|
|
+ if (zipos == null) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
InputStream inputStream = null;
|
|
InputStream inputStream = null;
|
|
|
|
|
|
- for(String url : urls){
|
|
|
|
- if(StringUtils.isNotEmpty(url)){
|
|
|
|
- try{
|
|
|
|
|
|
+ for (String url : urls) {
|
|
|
|
+ if (StringUtils.isNotEmpty(url)) {
|
|
|
|
+ try {
|
|
String fileName = null, symbol = "";
|
|
String fileName = null, symbol = "";
|
|
- if(url.contains("@@@")){
|
|
|
|
|
|
+ if (url.contains("@@@")) {
|
|
String[] array = url.split("@@@");
|
|
String[] array = url.split("@@@");
|
|
url = array[0];
|
|
url = array[0];
|
|
fileName = array[1];
|
|
fileName = array[1];
|
|
@@ -73,7 +75,7 @@ public class FileUtils {
|
|
//转换
|
|
//转换
|
|
byte[] bytes = CommonUtil.InputStreamToBytes(inputStream);
|
|
byte[] bytes = CommonUtil.InputStreamToBytes(inputStream);
|
|
|
|
|
|
- if(StringUtils.isEmpty(fileName)){
|
|
|
|
|
|
+ if (StringUtils.isEmpty(fileName)) {
|
|
fileName = url.substring(url.lastIndexOf("/") + 1);
|
|
fileName = url.substring(url.lastIndexOf("/") + 1);
|
|
symbol = "";
|
|
symbol = "";
|
|
}
|
|
}
|
|
@@ -83,7 +85,7 @@ public class FileUtils {
|
|
os.write(bytes);
|
|
os.write(bytes);
|
|
zipos.closeEntry();
|
|
zipos.closeEntry();
|
|
|
|
|
|
- }catch (Exception e){
|
|
|
|
|
|
+ } catch (Exception e) {
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
} finally {
|
|
} finally {
|
|
IoUtil.closeQuietly(inputStream);
|
|
IoUtil.closeQuietly(inputStream);
|
|
@@ -91,7 +93,7 @@ public class FileUtils {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- }catch (Exception e){
|
|
|
|
|
|
+ } catch (Exception e) {
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
} finally {
|
|
} finally {
|
|
IoUtil.closeQuietly(os);
|
|
IoUtil.closeQuietly(os);
|
|
@@ -103,26 +105,6 @@ public class FileUtils {
|
|
* 压缩图片
|
|
* 压缩图片
|
|
*/
|
|
*/
|
|
public static byte[] resizeImage(byte[] srcImgData, float reduceMultiple) throws IOException {
|
|
public static byte[] resizeImage(byte[] srcImgData, float reduceMultiple) throws IOException {
|
|
- BufferedImage bi = ImageIO.read(new ByteArrayInputStream(srcImgData));
|
|
|
|
- /*int width = (int) (bi.getWidth() * reduceMultiple);
|
|
|
|
- int height = (int) (bi.getHeight() * reduceMultiple);*/
|
|
|
|
- int width = 600;
|
|
|
|
- int height = 800;
|
|
|
|
- Image image = bi.getScaledInstance(width, height, Image.SCALE_SMOOTH);
|
|
|
|
- BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
|
|
|
- Graphics g = tag.getGraphics();
|
|
|
|
- g.setColor(Color.RED);
|
|
|
|
- g.drawImage(image, 0, 0, null);
|
|
|
|
- g.dispose();
|
|
|
|
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
|
|
|
- ImageIO.write(tag, "JPEG", bOut);
|
|
|
|
- return bOut.toByteArray();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 压缩图片2
|
|
|
|
- */
|
|
|
|
- public static byte[] resizeImage2(byte[] srcImgData, float reduceMultiple) throws IOException {
|
|
|
|
BufferedImage bi = ImageIO.read(new ByteArrayInputStream(srcImgData));
|
|
BufferedImage bi = ImageIO.read(new ByteArrayInputStream(srcImgData));
|
|
int width = (int) (bi.getWidth() * reduceMultiple);
|
|
int width = (int) (bi.getWidth() * reduceMultiple);
|
|
int height = (int) (bi.getHeight() * reduceMultiple);
|
|
int height = (int) (bi.getHeight() * reduceMultiple);
|
|
@@ -138,90 +120,108 @@ public class FileUtils {
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 图片定位
|
|
|
|
|
|
+ * 设置图片的定位、大小和合并单元格处理
|
|
|
|
+ *
|
|
|
|
+ * @param sheet 工作表对象
|
|
|
|
+ * @param anchor 锚点对象,表示图片的位置和大小
|
|
|
|
+ * @param dataVO 数据值对象,包含插入图片的单元格坐标
|
|
*/
|
|
*/
|
|
public static void imageOrientation(Sheet sheet, ClientAnchor anchor, DataVO dataVO) {
|
|
public static void imageOrientation(Sheet sheet, ClientAnchor anchor, DataVO dataVO) {
|
|
|
|
+ // 设置图片距左边和上边的偏移量
|
|
anchor.setDx1(Units.pixelToEMU(5));
|
|
anchor.setDx1(Units.pixelToEMU(5));
|
|
anchor.setDy1(Units.pixelToEMU(5));
|
|
anchor.setDy1(Units.pixelToEMU(5));
|
|
|
|
+ // 设置图片右下角所在单元格的行列号与左上角一致
|
|
anchor.setCol2(anchor.getCol1());
|
|
anchor.setCol2(anchor.getCol1());
|
|
anchor.setRow2(anchor.getRow1());
|
|
anchor.setRow2(anchor.getRow1());
|
|
- int k = getMergedRegionIndex(sheet, CommonUtil.join(dataVO.getX(), dataVO.getY(), dataVO.getX(), dataVO.getY(),","));
|
|
|
|
- if(k>-1){
|
|
|
|
- /*如果是合并单元格,则锚点第二坐标设置为合并区右下角单元格坐标*/
|
|
|
|
|
|
+ // 判断当前单元格是否属于一个合并单元格
|
|
|
|
+ int k = getMergedRegionIndex(sheet, CommonUtil.join(dataVO.getX(), dataVO.getY(), dataVO.getX(), dataVO.getY(), ","));
|
|
|
|
+ if (k > -1) {
|
|
|
|
+ // 如果是合并单元格,则锚点第一坐标设置为合并区左上角单元格坐标,第二坐标设置为合并区右下角单元格坐标
|
|
CellRangeAddress ca = sheet.getMergedRegion(k);
|
|
CellRangeAddress ca = sheet.getMergedRegion(k);
|
|
anchor.setCol1(ca.getFirstColumn());
|
|
anchor.setCol1(ca.getFirstColumn());
|
|
anchor.setRow1(ca.getFirstRow());
|
|
anchor.setRow1(ca.getFirstRow());
|
|
anchor.setCol2(ca.getLastColumn());
|
|
anchor.setCol2(ca.getLastColumn());
|
|
anchor.setRow2(ca.getLastRow());
|
|
anchor.setRow2(ca.getLastRow());
|
|
}
|
|
}
|
|
- int dx=(int)(sheet.getColumnWidthInPixels(anchor.getCol2())+3);
|
|
|
|
- int dy=Units.pointsToPixel(sheet.getRow(anchor.getRow2()).getHeightInPoints())-5;
|
|
|
|
|
|
+ // 计算图片宽度和高度的像素值,并将像素值转换成EMUs(English Metric Units)
|
|
|
|
+ int dx = (int) (sheet.getColumnWidthInPixels(anchor.getCol2()) + 3);
|
|
|
|
+ int dy = Units.pointsToPixel(sheet.getRow(anchor.getRow2()).getHeightInPoints()) - 5;
|
|
anchor.setDx2(Units.pixelToEMU(dx));
|
|
anchor.setDx2(Units.pixelToEMU(dx));
|
|
anchor.setDy2(Units.pixelToEMU(dy));
|
|
anchor.setDy2(Units.pixelToEMU(dy));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 获取指定单元格所在的合并单元格的下标
|
|
|
|
+ *
|
|
|
|
+ * @param sheet 工作表对象
|
|
|
|
+ * @param coords 单元格坐标字符串,格式为"左上角行号,左上角列号,右下角行号,右下角列号"
|
|
|
|
+ * @return 返回指定单元格所在的合并单元格下标,如果不存在则返回-1
|
|
|
|
+ */
|
|
public static int getMergedRegionIndex(Sheet sheet, String coords) {
|
|
public static int getMergedRegionIndex(Sheet sheet, String coords) {
|
|
|
|
+ // 遍历所有合并单元格
|
|
for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
|
|
for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
|
|
CellRangeAddress ca = sheet.getMergedRegion(i);
|
|
CellRangeAddress ca = sheet.getMergedRegion(i);
|
|
int firstColumn = ca.getFirstColumn();
|
|
int firstColumn = ca.getFirstColumn();
|
|
int lastColumn = ca.getLastColumn();
|
|
int lastColumn = ca.getLastColumn();
|
|
int firstRow = ca.getFirstRow();
|
|
int firstRow = ca.getFirstRow();
|
|
int lastRow = ca.getLastRow();
|
|
int lastRow = ca.getLastRow();
|
|
- Matcher mu = CommonUtil.matcher("(\\d{1,3}),(\\d{1,3}),(\\d{1,3}),(\\d{1,3})",coords);
|
|
|
|
- /*合并单元格四个角坐标,只要任意一个在落在将要合并的区域里面意味着两者重合,就必须拆分前者*/
|
|
|
|
- List<Integer[]> corners = Arrays.asList(new Integer[]{firstColumn,firstRow},new Integer[]{lastColumn,firstRow},new Integer[]{firstColumn,lastRow},new Integer[]{lastColumn,lastRow});
|
|
|
|
- if(mu.find()){
|
|
|
|
|
|
+ // 解析指定单元格坐标字符串
|
|
|
|
+ Matcher mu = CommonUtil.matcher("(\\d{1,3}),(\\d{1,3}),(\\d{1,3}),(\\d{1,3})", coords);
|
|
|
|
+ // 判断是否有重叠部分,如果有则返回对应的合并单元格下标
|
|
|
|
+ List<Integer[]> corners = Arrays.asList(new Integer[]{firstColumn, firstRow}, new Integer[]{lastColumn, firstRow}, new Integer[]{firstColumn, lastRow}, new Integer[]{lastColumn, lastRow});
|
|
|
|
+ if (mu.find()) {
|
|
int firstColumn2 = mu.group(1) == null ? 0 : Integer.parseInt(mu.group(1));
|
|
int firstColumn2 = mu.group(1) == null ? 0 : Integer.parseInt(mu.group(1));
|
|
int lastColumn2 = mu.group(3) == null ? 0 : Integer.parseInt(mu.group(3));
|
|
int lastColumn2 = mu.group(3) == null ? 0 : Integer.parseInt(mu.group(3));
|
|
int firstRow2 = mu.group(2) == null ? 0 : Integer.parseInt(mu.group(2));
|
|
int firstRow2 = mu.group(2) == null ? 0 : Integer.parseInt(mu.group(2));
|
|
int lastRow2 = mu.group(4) == null ? 0 : Integer.parseInt(mu.group(4));
|
|
int lastRow2 = mu.group(4) == null ? 0 : Integer.parseInt(mu.group(4));
|
|
- for(Integer[] corner:corners){
|
|
|
|
- if(firstColumn2<=corner[0]&&corner[0]<=lastColumn2&&firstRow2<=corner[1]&&corner[1]<=lastRow2){
|
|
|
|
|
|
+ for (Integer[] corner : corners) {
|
|
|
|
+ if (firstColumn2 <= corner[0] && corner[0] <= lastColumn2 && firstRow2 <= corner[1] && corner[1] <= lastRow2) {
|
|
return i;
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ // 如果没有重叠部分,则返回-1
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* 合并方法
|
|
* 合并方法
|
|
*/
|
|
*/
|
|
- public static void mergePdfPublicMethods(List<String> urlList, String localImgUrl){
|
|
|
|
|
|
+ public static void mergePdfPublicMethods(List<String> urlList, String localImgUrl) {
|
|
PdfReader reader = null;
|
|
PdfReader reader = null;
|
|
|
|
|
|
Document doc = new Document();
|
|
Document doc = new Document();
|
|
PdfCopy pdfCopy = null;
|
|
PdfCopy pdfCopy = null;
|
|
- try{
|
|
|
|
|
|
+ try {
|
|
pdfCopy = new PdfCopy(doc, new FileOutputStream(localImgUrl));
|
|
pdfCopy = new PdfCopy(doc, new FileOutputStream(localImgUrl));
|
|
int pageCount;
|
|
int pageCount;
|
|
doc.open();
|
|
doc.open();
|
|
|
|
|
|
- for(String urlStr : urlList){
|
|
|
|
- try{
|
|
|
|
|
|
+ for (String urlStr : urlList) {
|
|
|
|
+ try {
|
|
//获取OSS文件输入流
|
|
//获取OSS文件输入流
|
|
reader = new PdfReader(CommonUtil.getOSSInputStream(urlStr));
|
|
reader = new PdfReader(CommonUtil.getOSSInputStream(urlStr));
|
|
|
|
|
|
pageCount = reader.getNumberOfPages();
|
|
pageCount = reader.getNumberOfPages();
|
|
|
|
|
|
- for(int i = 0; i < pageCount; ++i){
|
|
|
|
|
|
+ for (int i = 0; i < pageCount; ++i) {
|
|
int is = i + 1;
|
|
int is = i + 1;
|
|
- pdfCopy.addPage(pdfCopy.getImportedPage(reader,is));
|
|
|
|
|
|
+ pdfCopy.addPage(pdfCopy.getImportedPage(reader, is));
|
|
}
|
|
}
|
|
- }catch (Exception e){
|
|
|
|
|
|
+ } catch (Exception e) {
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
} finally {
|
|
} finally {
|
|
- if(reader != null){
|
|
|
|
|
|
+ if (reader != null) {
|
|
reader.close();
|
|
reader.close();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- }catch (Exception e){
|
|
|
|
|
|
+ } catch (Exception e) {
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
} finally {
|
|
} finally {
|
|
- if(pdfCopy != null){
|
|
|
|
|
|
+ if (pdfCopy != null) {
|
|
pdfCopy.flush();
|
|
pdfCopy.flush();
|
|
pdfCopy.close();
|
|
pdfCopy.close();
|
|
}
|
|
}
|