引入依赖包
< ! -- poi实现Excel 导入导出-- >
< dependency>
< groupId> org. apache. poi< / groupId>
< artifactId> poi< / artifactId>
< version> 4.0 .0 < / version>
< / dependency>
< dependency>
< groupId> org. apache. poi< / groupId>
< artifactId> poi- ooxml< / artifactId>
< version> 4.0 .0 < / version>
< / dependency>
< ! -- itextpdf依赖注入包-- >
< ! -- https: / / mvnrepository. com/ artifact/ com. itextpdf/ itextpdf -- >
< dependency>
< groupId> com. itextpdf< / groupId>
< artifactId> itextpdf< / artifactId>
< version> 5.5 .13 .3 < / version>
< / dependency>
< ! -- https: / / mvnrepository. com/ artifact/ com. itextpdf/ itext7- core -- >
< dependency>
< groupId> com. itextpdf< / groupId>
< artifactId> itext7- core< / artifactId>
< version> 7.2 .5 < / version>
< type> pom< / type>
< / dependency>
构建表格内容
private static final float width = 60f ;
private static final float fitWidthRatio = 0.9f ;
private static final float height = 60f ;
private static final float fitHeightRatio = 0.9f ;
public static PdfPTable structureTable ( Workbook workbook, String fileName, int sheetIndex, float totalWidth) {
try {
Sheet sheet = workbook. getSheetAt ( sheetIndex) ;
float [ ] widths = ExcelUtils . getColWidthRatio ( sheet) ;
PdfPTable table = new PdfPTable ( widths) ;
table. setWidthPercentage ( 90 ) ;
table. setTotalWidth ( totalWidth) ;
table. setLockedWidth ( true ) ;
int colNumber = widths. length;
for ( int rowIndex = 0 ; rowIndex < sheet. getPhysicalNumberOfRows ( ) ; rowIndex++ ) {
Row row = sheet. getRow ( rowIndex) ;
if ( row != null ) {
for ( int colIndex = 0 ; colIndex < colNumber; colIndex++ ) {
Cell cell = row. getCell ( colIndex) ;
String value = "" ;
if ( cell == null ) {
cell = row. createCell ( colIndex) ;
} else {
value = ExcelUtils . getCellValue ( cell) ;
}
org. apache. poi. ss. usermodel. Font excelFont = ExcelUtils . getExcelFont ( workbook, cell, fileName) ;
short fontSize = excelFont. getFontHeightInPoints ( ) ;
Font font = createFont ( excelFont. getFontName ( ) , fontSize, excelFont. getBold ( ) ) ;
PdfPCell pdfPCell = new PdfPCell ( new Phrase ( value, font) ) ;
pdfPCell. setBorder ( 0 ) ;
pdfPCell. setUseAscender ( true ) ;
pdfPCell. setHorizontalAlignment ( PdfPCell . ALIGN_CENTER) ;
pdfPCell. setVerticalAlignment ( PdfPCell . ALIGN_MIDDLE) ;
pdfPCell. setMinimumHeight ( row. getHeightInPoints ( ) ) ;
List < PictureInfo > pictureInfos = ExcelUtils . getPictureInfo ( sheet, rowIndex, rowIndex, colIndex, colIndex, true ) ;
if ( ! pictureInfos. isEmpty ( ) ) {
for ( PictureInfo pictureInfo : pictureInfos) {
Image image = Image . getInstance ( pictureInfo. getPictureData ( ) ) ;
image. scaleToFit ( width, height) ;
pdfPCell = new PdfPCell ( image) ;
pdfPCell. setUseAscender ( true ) ;
pdfPCell. setHorizontalAlignment ( PdfPCell . ALIGN_CENTER) ;
pdfPCell. setVerticalAlignment ( PdfPCell . ALIGN_MIDDLE) ;
}
}
if ( ExcelUtils . ifMergedRegions ( sheet, rowIndex, colIndex) ) {
List < Integer > mergedRegions = ExcelUtils . getMergedRegions ( sheet, rowIndex, colIndex) ;
if ( mergedRegions. get ( 0 ) == rowIndex) {
pdfPCell. setBorderWidthLeft ( cell. getCellStyle ( ) . getBorderLeft ( ) . getCode ( ) ) ;
pdfPCell. setBorderWidthTop ( cell. getCellStyle ( ) . getBorderTop ( ) . getCode ( ) ) ;
}
if ( mergedRegions. get ( 1 ) == sheet. getPhysicalNumberOfRows ( ) - 1 ) {
pdfPCell. setBorderWidthBottom ( sheet. getRow ( mergedRegions. get ( 1 ) ) . getCell ( mergedRegions. get ( 2 ) ) . getCellStyle ( ) . getBorderBottom ( ) . getCode ( ) ) ;
}
int rowspan = mergedRegions. get ( 1 ) - mergedRegions. get ( 0 ) + 1 ;
int colspan = mergedRegions. get ( 3 ) - mergedRegions. get ( 2 ) + 1 ;
if ( mergedRegions. get ( 0 ) < rowIndex && rowIndex <= mergedRegions. get ( 1 ) && mergedRegions. get ( 2 ) <= colIndex && colIndex <= mergedRegions. get ( 3 ) ) {
continue ;
}
pdfPCell. setRowspan ( rowspan) ;
pdfPCell. setColspan ( colspan) ;
colIndex = colIndex + colspan - 1 ;
} else {
pdfPCell. setBorderWidthTop ( cell. getCellStyle ( ) . getBorderTop ( ) . getCode ( ) ) ;
pdfPCell. setBorderWidthLeft ( cell. getCellStyle ( ) . getBorderLeft ( ) . getCode ( ) ) ;
}
if ( rowIndex == sheet. getPhysicalNumberOfRows ( ) - 1 ) {
pdfPCell. setBorderWidthBottom ( cell. getCellStyle ( ) . getBorderBottom ( ) . getCode ( ) ) ;
}
if ( colIndex == row. getPhysicalNumberOfCells ( ) - 1 ) {
pdfPCell. setBorderWidthRight ( cell. getCellStyle ( ) . getBorderRight ( ) . getCode ( ) ) ;
}
table. addCell ( pdfPCell) ;
}
} else {
PdfPCell pdfPCell = new PdfPCell ( new Phrase ( "" ) ) ;
pdfPCell. setBorder ( 0 ) ;
pdfPCell. setMinimumHeight ( 13 ) ;
table. addCell ( pdfPCell) ;
}
}
return table;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
return null ;
}
引用到的工具方法
1.构建字体对象
private static final String FONT_ARIAL = "arial.ttf" ;
private static final String FONT_ARIAL_NAME = "arial" ;
private static final String FONT_YH = "msyh.ttc,0" ;
private static final String FONT_YH_NAME = "微软雅黑" ;
private static final String FONT_HT = "simhei.ttf" ;
private static final String FONT_HT_NAME = "黑体" ;
private static final String FONT_FANG_SONG = "simfang.ttf" ;
private static final String FONT_FANG_SONG_NAME = "仿宋" ;
private static final String FONT_SONG = "simsun.ttc,0" ;
private static final String FONT_SONG_NAME = "宋体" ;
private static final String FONT_DENG = "Deng.ttf" ;
private static final String FONT_DENG_NAME = "等线" ;
private static final String FONT_KAI = "simkai.ttf" ;
private static final String FONT_KAI_NAME = "楷体" ;
public static Font createFont ( String fontName, int fontSize, boolean fontBold) {
BaseFont baseFont = createBaseFont ( fontName) ;
if ( baseFont == null ) {
baseFont = createBaseFont ( FONT_YH_NAME) ;
}
return new Font ( baseFont, fontSize, fontBold ? Font . BOLD : Font . NORMAL, BaseColor . BLACK) ;
}
private static BaseFont createBaseFont ( String fontName) {
String FONT_PATH = Objects . requireNonNull ( PdfUtils . class . getResource ( "/fonts/" ) ) . getPath ( ) ;
try {
Map < String , BaseFont > fontMap = new HashMap < String , BaseFont > ( ) { {
put ( FONT_ARIAL_NAME, BaseFont . createFont ( FONT_PATH + FONT_ARIAL, BaseFont . IDENTITY_H, BaseFont . EMBEDDED) ) ;
put ( FONT_YH_NAME, BaseFont . createFont ( FONT_PATH + FONT_YH, BaseFont . IDENTITY_H, BaseFont . EMBEDDED) ) ;
put ( FONT_HT_NAME, BaseFont . createFont ( FONT_PATH + FONT_HT, BaseFont . IDENTITY_H, BaseFont . EMBEDDED) ) ;
put ( FONT_SONG_NAME, BaseFont . createFont ( FONT_PATH + FONT_SONG, BaseFont . IDENTITY_H, BaseFont . EMBEDDED) ) ;
put ( FONT_FANG_SONG_NAME, BaseFont . createFont ( FONT_PATH + FONT_FANG_SONG, BaseFont . IDENTITY_H, BaseFont . EMBEDDED) ) ;
put ( FONT_DENG_NAME, BaseFont . createFont ( FONT_PATH + FONT_DENG, BaseFont . IDENTITY_H, BaseFont . EMBEDDED) ) ;
put ( FONT_KAI_NAME, BaseFont . createFont ( FONT_PATH + FONT_KAI, BaseFont . IDENTITY_H, BaseFont . EMBEDDED) ) ;
} } ;
return fontMap. get ( fontName) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
return null ;
}
2.获取表格字体格式
public static Font getExcelFont ( Workbook workbook, Cell cell, String excelName) {
if ( excelName. endsWith ( "xls" ) ) {
return ( ( HSSFCell ) cell) . getCellStyle ( ) . getFont ( workbook) ;
}
return ( ( XSSFCell ) cell) . getCellStyle ( ) . getFont ( ) ;
}
3.获取表格中列宽占比情况
public static float [ ] getColWidthRatio ( Sheet sheet) {
int maxRow = getMaxRow ( sheet) ;
Row row = sheet. getRow ( maxRow) ;
int cellNumber = row. getPhysicalNumberOfCells ( ) ;
int [ ] colWidths = new int [ cellNumber] ;
int sum = 0 ;
for ( int i = 0 ; i < cellNumber; i++ ) {
Cell cell = row. getCell ( i) ;
if ( cell != null ) {
colWidths[ i] = sheet. getColumnWidth ( i) ;
sum += sheet. getColumnWidth ( i) ;
}
}
float [ ] colWidthPer = new float [ cellNumber] ;
for ( int i = 0 ; i < cellNumber; i++ ) {
colWidthPer[ i] = ( float ) colWidths[ i] / sum * 100 ;
}
return colWidthPer;
}
public static int getMaxRow ( Sheet sheet) {
int maxCell = 0 ;
int maxRow = 0 ;
for ( int i = 0 ; i < sheet. getPhysicalNumberOfRows ( ) ; i++ ) {
Row row = sheet. getRow ( i) ;
if ( row != null && maxCell < row. getPhysicalNumberOfCells ( ) ) {
maxCell = row. getPhysicalNumberOfCells ( ) ;
maxRow = i;
}
}
return maxRow;
}
4.读取表格<列>属性值
public static String getCellValue ( Cell cell) {
String value = "" ;
if ( ! isEmptyCell ( cell) ) {
switch ( cell. getCellType ( ) ) {
case STRING:
value = cell. getStringCellValue ( ) . trim ( ) ;
break ;
case NUMERIC:
if ( DateUtil . isCellDateFormatted ( cell) ) {
Date date = cell. getDateCellValue ( ) ;
value = DateUtils . dateToString ( date, "yyyy-MM-dd HH:mm:ss" ) ;
} else {
value = String . valueOf ( cell. getNumericCellValue ( ) ) ;
}
break ;
case BOOLEAN:
value = String . valueOf ( cell. getBooleanCellValue ( ) ) ;
break ;
default :
value = "" ;
break ;
}
}
return value;
}
5.判断表格是否存在跨行跨列情况,并获取跨行跨列单元格基础属性
public static boolean ifMergedRegions ( Sheet sheet, int rowIndex, int cellIndex) {
for ( int i = 0 ; i < sheet. getNumMergedRegions ( ) ; i++ ) {
CellRangeAddress mergedRegion = sheet. getMergedRegion ( i) ;
int firstRow = mergedRegion. getFirstRow ( ) ;
int lastRow = mergedRegion. getLastRow ( ) ;
int firstColumn = mergedRegion. getFirstColumn ( ) ;
int lastColumn = mergedRegion. getLastColumn ( ) ;
if ( firstRow <= rowIndex && rowIndex <= lastRow) {
if ( firstColumn <= cellIndex && cellIndex <= lastColumn) {
return true ;
}
}
}
return false ;
}
public static List < Integer > getMergedRegions ( Sheet sheet, int rowIndex, int cellIndex) {
List < Integer > merge = null ;
for ( int i = 0 ; i < sheet. getNumMergedRegions ( ) ; i++ ) {
CellRangeAddress mergedRegion = sheet. getMergedRegion ( i) ;
int firstRow = mergedRegion. getFirstRow ( ) ;
int lastRow = mergedRegion. getLastRow ( ) ;
int firstColumn = mergedRegion. getFirstColumn ( ) ;
int lastColumn = mergedRegion. getLastColumn ( ) ;
if ( firstRow <= rowIndex && rowIndex <= lastRow) {
if ( firstColumn <= cellIndex && cellIndex <= lastColumn) {
merge = Arrays . asList ( firstRow, lastRow, firstColumn, lastColumn) ;
break ;
}
}
}
return merge;
}
6.1读取表格中图片对象
public static List < PictureInfo > getXLSPictureInfo ( HSSFSheet sheet, Integer startCurrentRow, Integer endCurrentRow, Integer startCurrentCol, Integer endCurrentCol, Boolean isInterval) {
List < PictureInfo > pictureInfos = new ArrayList < > ( ) ;
try {
HSSFPatriarch drawingPatriarch = sheet. getDrawingPatriarch ( ) ;
if ( drawingPatriarch != null ) {
List < HSSFShape > shapeList = drawingPatriarch. getChildren ( ) ;
for ( HSSFShape hssfShape : shapeList) {
if ( hssfShape instanceof HSSFPicture && hssfShape. getAnchor ( ) instanceof HSSFClientAnchor ) {
HSSFPicture picture = ( HSSFPicture ) hssfShape;
HSSFClientAnchor anchor = ( HSSFClientAnchor ) hssfShape. getAnchor ( ) ;
if ( isLoadPicture ( startCurrentRow, endCurrentRow, startCurrentCol, endCurrentCol,
anchor. getRow1 ( ) , anchor. getRow2 ( ) , anchor. getCol1 ( ) , anchor. getCol2 ( ) , isInterval) ) {
pictureInfos. add ( new PictureInfo ( anchor. getRow1 ( ) , anchor. getRow2 ( ) , anchor. getCol1 ( ) , anchor. getCol2 ( ) ,
picture. getPictureData ( ) . getData ( ) , picture. getPictureData ( ) . getMimeType ( ) ) ) ;
}
}
}
}
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
return pictureInfos;
}
public static List < PictureInfo > getXSSFSPictureInfo ( XSSFSheet sheet, Integer startCurrentRow, Integer endCurrentRow, Integer startCurrentCol, Integer endCurrentCol, Boolean isInterval) {
List < PictureInfo > pictureInfos = new ArrayList < > ( ) ;
try {
XSSFDrawing drawingPatriarch = sheet. getDrawingPatriarch ( ) ;
if ( drawingPatriarch != null ) {
List < XSSFShape > shapeList = drawingPatriarch. getShapes ( ) ;
for ( XSSFShape hssfShape : shapeList) {
if ( hssfShape instanceof XSSFPicture && hssfShape. getAnchor ( ) instanceof XSSFClientAnchor ) {
XSSFPicture picture = ( XSSFPicture ) hssfShape;
XSSFClientAnchor anchor = ( XSSFClientAnchor ) hssfShape. getAnchor ( ) ;
if ( isLoadPicture ( startCurrentRow, endCurrentRow, startCurrentCol, endCurrentCol,
anchor. getRow1 ( ) , anchor. getRow2 ( ) , anchor. getCol1 ( ) , anchor. getCol2 ( ) , isInterval) ) {
pictureInfos. add ( new PictureInfo ( anchor. getRow1 ( ) , anchor. getRow2 ( ) , anchor. getCol1 ( ) , anchor. getCol2 ( ) ,
picture. getPictureData ( ) . getData ( ) , picture. getPictureData ( ) . getMimeType ( ) ) ) ;
}
}
}
}
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
return pictureInfos;
}
public static boolean isLoadPicture ( Integer startCurrentRow, Integer endCurrentRow, Integer startCurrentCol, Integer endCurrentCol,
int startPictureRow, int endPictureRow, int startPictureCol, int endPictureCol, Boolean isInterval) {
int _startCurrentRow = startCurrentRow == null ? startPictureRow : startCurrentRow;
int _endCurrentRow = endCurrentRow == null ? endPictureRow : endCurrentRow;
int _startCurrentCol = startCurrentCol == null ? startPictureCol : startCurrentCol;
int _endCurrentCol = endCurrentCol == null ? endPictureCol : endCurrentCol;
if ( ! isInterval) {
return ( _startCurrentRow <= startPictureRow && _endCurrentRow >= endPictureRow &&
_startCurrentCol <= startPictureCol && _endCurrentCol >= endPictureCol) ;
} else {
return ( ( Math . abs ( _endCurrentRow - _startCurrentRow) + Math . abs ( endPictureRow - startPictureRow) >= Math . abs ( _endCurrentRow + _startCurrentRow - endPictureRow - startPictureRow) ) &&
( Math . abs ( _endCurrentCol - _startCurrentCol) + Math . abs ( endPictureCol - startPictureCol) >= Math . abs ( _endCurrentCol + _startCurrentCol - endPictureCol - startPictureCol) ) ) ;
}
}
6.2创建图片实体类对象
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PictureInfo {
private int startRow;
private int endRow;
private int startCol;
private int endCol;
private byte [ ] pictureData;
private String type;
@Override
public String toString ( ) {
return "PictureInfo{" +
"startRow=" + startRow +
", endRow=" + endRow +
", startCol=" + startCol +
", endCol=" + endCol +
'}' ;
}
}
开始测试
public static void main ( String [ ] args) {
RectangleReadOnly rectangleReadOnly = new RectangleReadOnly ( PageSize . A4) ;
try {
File file = new File ( "D:/test/1/1.xls" ) ;
Workbook workbook = new HSSFWorkbook ( new FileInputStream ( file) ) ;
Document document = new Document ( rectangleReadOnly) ;
long l = System . currentTimeMillis ( ) ;
PdfWriter . getInstance ( document, new FileOutputStream ( "D:/test/1/" + l + ".pdf" ) ) ;
document. open ( ) ;
document. setMargins ( 20 , 20 , 30 , 30 ) ;
PdfPTable pdfPTable = structureTable ( workbook, file. getName ( ) , 0 , rectangleReadOnly. getWidth ( ) - 40 ) ;
document. add ( pdfPTable) ;
document. close ( ) ;
Desktop . getDesktop ( ) . open ( new File ( "D:/test/1/" + l + ".pdf" ) ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}