需求:将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文件:

JAVA Aspose 将Excel 转为图片 java poi excel转pdf_java

转化后的PDF文件:

JAVA Aspose 将Excel 转为图片 java poi excel转pdf_java_02

 

测试代码:

// 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;
	}
}