需求:将Excel转化为PDF,支持图片,只单个sheet
要求:1、开源免费;2、支持跨平台
设计:1. 采用POI读取Excel文件;2. 采用itext生成PDF文件。
注:如果费用许可的情况下,建议使用Aspose(可跨平台,收费,不开源)。
开发难点:
1. 将POI标准转化为Itext标准,包括单元格内容,字体,样式,单元格的合并等;
2. Excel文件x轴可以滚动,而PDF文件宽度是固定的,转化后的PDF内容可能会出现挤压的情况。
思路:1. 先将poi对转化为标准对象,如将POI的颜色转化为RGB;2. 将标准对象转化为itext对象。
转换事项:
1. 单元格类型:常规、数值、文本等。
2. 对齐方式:水平对齐只支持左对齐、居中、右对齐,默认左对齐;垂直对齐方式只顶端对齐、垂直居中、底端对齐,默认底端对齐。
3. 文本的字体(暂不支持,目前固定为STSong-Light)、颜色(支持)、大小(支持)、是否加粗(支持),是否倾斜(支持),是否有下划线(支持),是否自动换行(支持)
4. 框线:下框线、上框线、左框线、右框线(仅设置边框颜色和边框宽度)
5. 填充色(背景色):支持。
6. 单元格的高度和宽度
遗留问题(后续改善):
1. excel不支持黑色背景。
2. excel相邻单元格都有边框时,PDF文件边框变粗。
3. 当excel单元格处在图片区域,PDF中该单元格无文本。
4. 当excel文件存在多张图片有重合区域时,PDF只有其中的一张图片(起始单元格最靠前的图片)。
5. excel单元格字体加粗、倾斜、下划线,pdf只有加粗、下划线,缺少倾斜。
6. 部分情况pdf样式失真。
7.目前该文主要是验证excel转pdf,后期会更新优化后方案。
示例(excel2003文件转化为pdf)
excel2003文件:
转化后的PDF文件:
测试代码:
// poi和itext将Excel转化为PDF(支持图片)
String pdf = "F:/Users/zyj/Desktop/2019-09-27 自由报表/插件测试/excel2pdf_new.pdf";
Xls2Pdf xls2Pdf = new Xls2Pdf(xls, 0);
xls2Pdf.savePdf(pdf);
poi读取xls文件,生成PDF的代码:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFPictureData;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;
import com.itextpdf.text.BadElementException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
/**
* Excel2003文件转化为PDF文件
*
* @author zyj
* @date 2019-10-18
*/
public class Xls2Pdf {
private HSSFWorkbook _wb = null;
private int _sheetIndex = 0;
private HSSFSheet _sheet = null;
// 文本中的合并单元格
private List<CellRangeAddress> _ranges = null;
// 单个Sheet中所有的图片信息
private Map<String, HSSFPictureData> _pics = null;
// 图片中的最后一个单元格位置
private Integer[] _lastCell = null;
/**
* 构造函数
*
* @param excel excel2003文件的全路径
* @param sheetindex sheet索引
* @throws IOException
*/
public Xls2Pdf(String excel, int sheetIndex) throws IOException {
InputStream input = new FileInputStream(excel);
HSSFWorkbook wb = new HSSFWorkbook(input);
this._wb = wb;
this._sheetIndex = sheetIndex;
}
/**
* 构造函数
*
* @param wb excel工作薄
* @param sheetIndex sheet索引
*/
public Xls2Pdf(HSSFWorkbook wb, int sheetIndex) {
this._wb = wb;
this._sheetIndex = sheetIndex;
}
/**
* 保存为pdf文件
*
* @param pdf pdf文件的全路径
* @throws IOException
* @throws BadElementException
* @throws DocumentException
*/
public void savePdf(String pdf) throws IOException, BadElementException, DocumentException {
PdfPTable table = this.genPdfPTable();
// Step 1 — Create a Document
Document document = new Document();
// Step 2 — Get a PdfWriter instance
FileOutputStream output = new FileOutputStream(pdf);
PdfWriter.getInstance(document, output);
// Step 3 — Open the Document
document.open();
// Step 4 — Add content.
document.add(table);
// Step 5 — Close the Document
document.close();
}
/**
* 将sheet转化为PdfPTable
*
* @return PdfPTable对象
* @throws IOException
* @throws BadElementException
* @throws DocumentException
*/
public PdfPTable genPdfPTable() throws IOException, BadElementException, DocumentException {
if (this._wb == null) {
return null;
}
this._sheet = this._wb.getSheetAt(this._sheetIndex);
if (this._sheet == null) {
return null;
}
// 文本中的合并单元格
this._ranges = this._sheet.getMergedRegions();
// sheet中所有图片信息
this._pics = XlsHelper.getPictrues(this._wb, this._sheetIndex);
// sheet中最后一个单元格位置
this._lastCell = this.getLastCell();
PdfPTable table = new PdfPTable(this._lastCell[1] + 1);
// 遍历Sheet中的所有行
for (int i = 0; i <= this._lastCell[0]; i++) {
for (int j = 0; j <= this._lastCell[1]; j++) {
PdfPCell pdfpCell = this.genPdfPCell(i, j);
if (pdfpCell == null) {
continue;
}
table.addCell(pdfpCell);
j += pdfpCell.getColspan() - 1;
}
}
// sheet中每列的宽度
float totalWidth = 0;
float[] widths = new float[this._lastCell[1] + 1];
for (int i = 0; i <= this._lastCell[1]; i++) {
widths[i] = this._sheet.getColumnWidthInPixels(i);
totalWidth += widths[i];
}
// PDF宽度固定
table.setWidths(widths);
table.setTotalWidth(totalWidth);
table.setLockedWidth(true);
return table;
}
/**
* 将Exel单元格转化为PDF单元格
*
* @param rowIndex 行号
* @param colIndex 列号
* @return PDF单元格
* @throws IOException
* @throws BadElementException
*/
private PdfPCell genPdfPCell(int rowIndex, int colIndex) throws IOException, BadElementException {
// 如果该位置是合并区域的单元格,跳过。
if (this.merged(rowIndex, colIndex)) {
return null;
}
// 是否为图片的起始单元格
boolean isImg = this.imgCell(rowIndex, colIndex);
PdfPCell pdfpCell = null;
HSSFRow row = this._sheet.getRow(rowIndex);
if (row == null) {
// 空单元格,无边框
pdfpCell = new PdfPCell();
pdfpCell.setBorder(Rectangle.NO_BORDER);
} else {
HSSFCell cell = row.getCell(colIndex);
// 空单元格的处理
if (cell == null) {
cell = row.createCell(colIndex);
}
pdfpCell = Xls2PdfObject.parsePdfPCell(this._wb, cell);
if (!isImg) {
// 非图片,填充文本内容
Phrase phrase = Xls2PdfObject.parsePhrase(this._wb, cell);
pdfpCell.setPhrase(phrase);
}
}
if (isImg) {
// 设置图片信息,图片优先,可能占用多个单元格(图片涉及的单元格无文本内容,且只会有一张图片)
this.setImage(pdfpCell, rowIndex, colIndex);
} else {
// 设置文本的合并单元格
this.setRange(pdfpCell, rowIndex, colIndex);
}
// 设置单元格的高度
float height = this.getHeight(rowIndex, pdfpCell.getRowspan());
pdfpCell.setMinimumHeight(height);
return pdfpCell;
}
/**
* 设置文本的合并单元格
*
* @param pdfpCell
* @param rowIndex
* @param colIndex
*/
private void setRange(PdfPCell pdfpCell, int rowIndex, int colIndex) {
CellRangeAddress range = this.getCellRangeAddress(rowIndex, colIndex);
int rowspan = 1;
int colspan = 1;
if (range != null) {
rowspan = range.getLastRow() - range.getFirstRow() + 1;
colspan = range.getLastColumn() - range.getFirstColumn() + 1;
}
pdfpCell.setRowspan(rowspan);
pdfpCell.setColspan(colspan);
}
/**
* 设置图片信息,图片优先,可能占用多个单元格(图片涉及的单元格无文本内容,且只会有一张图片)
*
* @param pdfpCell
* @param rowIndex
* @param colIndex
* @throws IOException
* @throws BadElementException
*/
private void setImage(PdfPCell pdfpCell, int rowIndex, int colIndex) throws IOException, BadElementException {
for (Map.Entry<String, HSSFPictureData> entry : this._pics.entrySet()) {
int[] arr = XlsHelper.getImgPostion(entry.getKey());
if (arr[1] == rowIndex && arr[2] == colIndex) {
int rowspan = arr[3] - arr[1] + 1;
int colspan = arr[4] - arr[2] + 1;
pdfpCell.setRowspan(rowspan);
pdfpCell.setColspan(colspan);
// 内边距
pdfpCell.setPaddingLeft(arr[5] / 20.00f);
pdfpCell.setPaddingTop(arr[6] / 32.00f);
pdfpCell.setPaddingRight(arr[7] / 20.00f);
pdfpCell.setPaddingBottom(arr[8] / 32.00f);
byte[] bytes = entry.getValue().getData();
Image image = Image.getInstance(bytes);
pdfpCell.setImage(image);
break;
}
}
}
/**
* 单元格高度
*
* @param rowindex 单元格起始行号
* @param rowspan 单元格占用行数
* @return 高度,单位pt
*/
private float getHeight(int rowIndex, int rowSpan) {
float height = 0.00f;
for (int i = 0; i < rowSpan; i++) {
HSSFRow row = this._sheet.getRow(rowIndex + i);
if (row == null) {
height += this._sheet.getDefaultRowHeightInPoints();
} else {
height += row.getHeightInPoints();
}
}
return height;
}
/**
* 合并区域的单元格(不包括初始单元格)
*
* @param rowIndex 行号
* @param colIndex 列号
* @return false表示该位置不是合并单元格,或者是合并区域的起始单元格
*/
private boolean merged(int rowIndex, int colIndex) {
boolean isMerge = false;
// 文本合并区域的单元格
if (this._ranges != null && this._ranges.size() > 0) {
int num = this._ranges.size();
for (int i = 0; i < num; i++) {
CellRangeAddress range = this._ranges.get(i);
if (rowIndex > range.getFirstRow() && rowIndex <= range.getLastRow()) {
if (colIndex >= range.getFirstColumn() && colIndex <= range.getLastColumn()) {
isMerge = true;
}
}
}
}
// 图片合并区域的单元格
if (this._pics != null && this._pics.size() > 0) {
for (Map.Entry<String, HSSFPictureData> entry : this._pics.entrySet()) {
int[] arr = XlsHelper.getImgPostion(entry.getKey());
if (rowIndex > arr[1] && rowIndex <= arr[3]) {
if (colIndex >= arr[2] && colIndex <= arr[4]) {
isMerge = true;
}
}
}
}
return isMerge;
}
/**
* 单元格是否是图片的起始位置
*
* @param rowIndex 行号
* @param colIndex 列号
* @return 单元格是否是图片的起始位置
*/
private boolean imgCell(int rowIndex, int colIndex) {
if (this._pics == null || this._pics.size() == 0) {
return false;
}
for (Map.Entry<String, HSSFPictureData> entry : this._pics.entrySet()) {
int[] arr = XlsHelper.getImgPostion(entry.getKey());
if (arr[1] == rowIndex && arr[2] == colIndex) {
return true;
}
}
return false;
}
/**
* 如果单元格是文本合并区域的起始位置,返回合并区域;否则返回null
*
* @param rowIndex 行号
* @param colIndex 列号
* @return 合并区域
*/
private CellRangeAddress getCellRangeAddress(int rowIndex, int colIndex) {
if (this._ranges == null || this._ranges.size() == 0) {
return null;
}
int num = this._ranges.size();
for (int i = 0; i < num; i++) {
CellRangeAddress range = this._ranges.get(i);
if (range.getFirstColumn() == colIndex && range.getFirstRow() == rowIndex) {
return range;
}
}
return null;
}
/**
* sheet中最后一个单元格位置
*
* @return 行号,列号
*/
private Integer[] getLastCell() {
// 文本中最后一个单元格的位置
Integer[] lastTextCell = this.getLastTextCell();
// 图片中的最后一个单元格位置
Integer[] lastImgCell = this.getLastImgCell();
if (lastImgCell == null || lastImgCell.length == 0) {
return lastTextCell;
}
Integer[] lastCell = new Integer[] { 0, 0 };
lastCell[0] = lastTextCell[0] >= lastImgCell[0] ? lastTextCell[0] : lastImgCell[0];
lastCell[1] = lastTextCell[1] >= lastImgCell[1] ? lastTextCell[1] : lastImgCell[1];
return lastCell;
}
/**
* sheet中最后一个文本单元格
*
* @return 行号,列号
*/
private Integer[] getLastTextCell() {
int lastRowIndex = this._sheet.getLastRowNum();
int lastColIndex = 0;
for (int i = 0; i <= lastRowIndex; i++) {
HSSFRow row = this._sheet.getRow(i);
if (row == null) {
continue;
}
// 该行最后一个单元格的索引
int colIndex = row.getLastCellNum();
if (colIndex > lastColIndex) {
lastColIndex = colIndex;
}
}
return new Integer[] { lastRowIndex, lastColIndex - 1 };
}
/**
* sheet的最后一个图片单元格
*
* @return 行号,列号
*/
private Integer[] getLastImgCell() {
if (this._pics == null || this._pics.size() == 0) {
return null;
}
int lastRowIndex = 0;
int lastColIndex = 0;
for (Map.Entry<String, HSSFPictureData> entry : this._pics.entrySet()) {
int[] arr = XlsHelper.getImgPostion(entry.getKey());
if (arr[0] != this._sheetIndex) {
continue;
}
if (arr[3] > lastRowIndex) {
lastRowIndex = arr[3];
}
if (arr[4] > lastColIndex) {
lastColIndex = arr[4];
}
}
return new Integer[] { lastRowIndex, lastColIndex };
}
}
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.format.CellNumberFormatter;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.FontUnderline;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import com.itextpdf.text.Anchor;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
/**
* Excel2003中的poi对象转化为itext对象
*
* @author zyj
* @date 2019-10-23
*/
public class Xls2PdfObject {
/**
* HSSFCell转化为PdfPCell
*
* @param wb
* @param cell
* @return
*/
public static PdfPCell parsePdfPCell(HSSFWorkbook wb, HSSFCell cell) {
PdfPCell pdfpCell = new PdfPCell();
HSSFCellStyle cellStyle = cell.getCellStyle();
pdfpCell.setUseAscender(true);
// 水平对齐方式
HorizontalAlignment halign = cellStyle.getAlignment();
int halign_itext = parseHorizontalAlignmen(halign);
pdfpCell.setHorizontalAlignment(halign_itext);
// 垂直对齐方式
VerticalAlignment valign = cellStyle.getVerticalAlignment();
int valign_itext = parseVerticalAlignment(valign);
pdfpCell.setVerticalAlignment(valign_itext);
// 填充色(背景色)
// HSSFColor backgroundColor = cellStyle.getFillBackgroundColorColor();
HSSFColor backgroundColor = cellStyle.getFillForegroundColorColor();
BaseColor backgroundColor_itext = parseBackgroundColor(backgroundColor);
pdfpCell.setBackgroundColor(backgroundColor_itext);
// 自动换行
boolean noWrap = !cellStyle.getWrapText();
pdfpCell.setNoWrap(noWrap);
// 边框颜色设置
// 下框线
short borderColor = cellStyle.getBottomBorderColor();
HSSFColor color = wb.getCustomPalette().getColor(borderColor);
BaseColor baseColor = parseColor(color);
pdfpCell.setBorderColorBottom(baseColor);
// 上框线
borderColor = cellStyle.getTopBorderColor();
baseColor = parseColor(color);
pdfpCell.setBorderColorTop(baseColor);
// 左框线
borderColor = cellStyle.getLeftBorderColor();
baseColor = parseColor(color);
pdfpCell.setBorderColorLeft(baseColor);
// 右框线
borderColor = cellStyle.getRightBorderColor();
baseColor = parseColor(color);
pdfpCell.setBorderColorRight(baseColor);
// 边框样式
// 下边框
BorderStyle borderStyle = cellStyle.getBorderBottom();
float borderWidth = borderStyle.getCode() / 32.00f;
pdfpCell.setBorderWidthBottom(borderWidth);
// 上框线
borderStyle = cellStyle.getBorderTop();
pdfpCell.setBorderWidthTop(borderStyle.getCode() / 32.00f);
// 左框线
borderStyle = cellStyle.getBorderLeft();
pdfpCell.setBorderWidthLeft(borderStyle.getCode() / 32.00f);
// 右框线
borderStyle = cellStyle.getBorderRight();
pdfpCell.setBorderWidthRight(borderStyle.getCode() / 32.00f);
pdfpCell.normalize();
// pdfpCell.disableBorderSide(9);
return pdfpCell;
}
/**
* HSSFCell转化为Phrase
*
* @param wb
* @param cell
* @return
*/
public static Phrase parsePhrase(HSSFWorkbook wb, HSSFCell cell) {
HSSFCellStyle cellStyle = cell.getCellStyle();
double cellNumberValue = 0;
boolean isNumber = cell.getCellType() == CellType.NUMERIC;
if (cell.getCellType() == CellType.NUMERIC || cell.getCellType() == CellType.FORMULA) {
try {
cellNumberValue = cell.getNumericCellValue();
isNumber = true;
} catch (Exception e) {
isNumber = false;
}
}
int index = cellStyle.getFontIndexAsInt();
HSSFFont xlsFont = wb.getFontAt(index);
Font itextFont = parseFont(xlsFont);
String formatStr = cellStyle.getDataFormatString();
if (!"general".equals(formatStr.toLowerCase()) && isNumber) {
String numberFormat = formatStr;
int firstFormatIdx = formatStr.indexOf(";");
if (firstFormatIdx > 0) {
numberFormat = formatStr.substring(0, firstFormatIdx);
}
String formattedValue = new CellNumberFormatter(numberFormat).format(cellNumberValue);
Phrase phrase = new Phrase(formattedValue, itextFont);
return phrase;
}
cell.setCellType(CellType.STRING);
String text = cell.getStringCellValue();
Anchor anchor = new Anchor(text, itextFont);
anchor.setName(text);
return anchor;
}
/**
* HSSFFont转化为itext的Font
*
* @param xlsFont HSSFFont
* @return Font
*/
public static Font parseFont(HSSFFont xlsFont) {
// 字体名称,编码方式,,字体大小,字体样式,字体颜色
String fontName = xlsFont.getFontName();
// 字体编码
String encoding = "UniGB-UCS2-H";
// 未嵌入PDF字体
boolean embedded = BaseFont.EMBEDDED;
// 字体大小
float size = xlsFont.getFontHeightInPoints();
// Font itextFont = FontFactory.getFont(fontName, encoding, embedded, size);
Font itextFont = FontFactory.getFont("STSong-Light", encoding, embedded, size);
// 字体颜色
int colorIndex = xlsFont.getColor();
HSSFColor color = HSSFColor.getIndexHash().get(colorIndex);
BaseColor baseColor = parseColor(color);
itextFont.setColor(baseColor);
// 加粗、倾斜
boolean isItalic = xlsFont.getItalic();
boolean isBold = xlsFont.getBold();
if (isItalic && isBold) {
itextFont.setStyle(Font.BOLDITALIC);
} else if (isBold) {
itextFont.setStyle(Font.BOLD);
} else if (isItalic) {
itextFont.setStyle(Font.ITALIC);
}
// 下划线
FontUnderline underline = FontUnderline.valueOf(xlsFont.getUnderline());
if (underline != FontUnderline.NONE) {
itextFont.setStyle(Font.UNDERLINE);
}
return itextFont;
}
/**
* 水平对齐方式转化 - poi转化为itext
*
* @param halign poi的水平对齐方式
* @return itext的水平对齐方式
*/
public static int parseHorizontalAlignmen(HorizontalAlignment halign) {
int halign_itext = Element.ALIGN_LEFT;
// 获取单元格的水平对齐方式
switch (halign) {
case LEFT:
halign_itext = Element.ALIGN_LEFT;
break;
case CENTER:
halign_itext = Element.ALIGN_CENTER;
break;
case RIGHT:
halign_itext = Element.ALIGN_RIGHT;
break;
}
return halign_itext;
}
/**
* 垂直对齐方式 转化- poi转化为itext:
*
* @param valign poi的垂直对齐方式
* @return itext的垂直对齐方式
*/
public static int parseVerticalAlignment(VerticalAlignment valign) {
int valign_itext = Element.ALIGN_BOTTOM;
switch (valign) {
case TOP:
valign_itext = Element.ALIGN_TOP;
break;
case CENTER:
valign_itext = Element.ALIGN_MIDDLE;
break;
case BOTTOM:
valign_itext = Element.ALIGN_BOTTOM;
break;
}
return valign_itext;
}
/**
* 颜色转化 - HSSFColor转化为BaseColor
*
* @param color
* @return
*/
public static BaseColor parseColor(HSSFColor hssfColor) {
if (hssfColor == null) {
return new BaseColor(255, 255, 255);
}
short[] rgb = hssfColor.getTriplet();
return new BaseColor(rgb[0], rgb[1], rgb[2]);
}
/**
* 背景颜色转化(不支持黑色背景) - HSSFColor转化为BaseColor
*
* @param color
* @return
*/
public static BaseColor parseBackgroundColor(HSSFColor hssfColor) {
if (hssfColor == null) {
// 白色
return new BaseColor(255, 255, 255);
}
short[] rgb = hssfColor.getTriplet();
if (rgb[0] == 0 && rgb[1] == 0 && rgb[2] == 0) {
rgb = new short[] { 255, 255, 255 };
}
return new BaseColor(rgb[0], rgb[1], rgb[2]);
}
}
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFPicture;
import org.apache.poi.hssf.usermodel.HSSFPictureData;
import org.apache.poi.hssf.usermodel.HSSFShape;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
/**
* Excel2003的常用方法
*
* @author zyj
* @date 2019-10-14
*/
public class XlsHelper {
/**
* 根据图片主键获取图片所在位置
*
* @param key,格式: sheet索引_起始行号_起始列号_结束行号_结束列号_单元格内的左边距_上边距_右边距_下边距_uuid
* @return sheet索引,起始行号,起始列号,结束行号,结束列号,左边距,上边距,右边距,下边距
*/
public static int[] getImgPostion(String imgKey) {
String[] arr = StringUtils.split(imgKey, "_");
int[] position = new int[9];
for (int i = 0; i < 9; i++) {
position[i] = Integer.parseInt(arr[i]);
}
return position;
}
/**
* Excel的图片获取
*
* @param wb Excel的工作簿
* @return Excel的图片,键格式:sheet索引_起始行号_起始列号_结束行号_结束列号_单元格内的左边距_上边距_右边距_下边距_uuid
*/
public static Map<String, HSSFPictureData> getPictrues(HSSFWorkbook wb) {
Map<String, HSSFPictureData> map = new HashMap<String, HSSFPictureData>();
// getAllPictures方法只能获取不同的图片,如果Excel中存在相同的图片,只能得到一张图片
List<HSSFPictureData> pics = wb.getAllPictures();
if (pics.size() == 0) {
return map;
}
for (Integer sheetIndex = 0; sheetIndex < wb.getNumberOfSheets(); sheetIndex++) {
HSSFSheet sheet = wb.getSheetAt(sheetIndex);
HSSFPatriarch patriarch = sheet.getDrawingPatriarch();
if (patriarch == null) {
continue;
}
for (HSSFShape shape : patriarch.getChildren()) {
HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor();
if (shape instanceof HSSFPicture) {
HSSFPicture pic = (HSSFPicture) shape;
int picIndex = pic.getPictureIndex() - 1;
HSSFPictureData picData = pics.get(picIndex);
// 键格式:sheet索引_行号_列号_单元格内的上边距_单元格内的左边距_uuid
String key = sheetIndex + "_" + anchor.getRow1() + "_" + anchor.getCol1() + "_" + anchor.getRow2() + "_" + anchor.getCol2();
key += "_" + anchor.getDx1() + "_" + anchor.getDy1() + "_" + anchor.getDx2() + "_" + anchor.getDy2();
key += "_" + UUID.randomUUID();
map.put(key, picData);
}
}
}
return map;
}
/**
* Excel的图片获取
*
* @param wb Excel的工作簿
* @param sheetIndex sheet索引
* @return Excel的图片,键格式:sheet索引_起始行号_起始列号_结束行号_结束列号_单元格内的左边距_上边距_右边距_下边距_uuid
*/
public static Map<String, HSSFPictureData> getPictrues(HSSFWorkbook wb, int sheetIndex) {
Map<String, HSSFPictureData> map = new HashMap<String, HSSFPictureData>();
// getAllPictures方法只能获取不同的图片,如果Excel中存在相同的图片,只能得到一张图片
List<HSSFPictureData> pics = wb.getAllPictures();
if (pics.size() == 0) {
return map;
}
HSSFSheet sheet = wb.getSheetAt(sheetIndex);
HSSFPatriarch patriarch = sheet.getDrawingPatriarch();
if (patriarch == null) {
return map;
}
for (HSSFShape shape : patriarch.getChildren()) {
HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor();
if (shape instanceof HSSFPicture) {
HSSFPicture pic = (HSSFPicture) shape;
int picIndex = pic.getPictureIndex() - 1;
HSSFPictureData picData = pics.get(picIndex);
// 键格式:sheet索引_起始行号_起始列号_结束行号_结束列号_单元格内的左边距_上边距_右边距_下边距_uuid
String key = sheetIndex + "_" + anchor.getRow1() + "_" + anchor.getCol1() + "_" + anchor.getRow2() + "_" + anchor.getCol2();
key += "_" + anchor.getDx1() + "_" + anchor.getDy1() + "_" + anchor.getDx2() + "_" + anchor.getDy2();
key += "_" + UUID.randomUUID();
map.put(key, picData);
}
}
return map;
}
}