Skip to content

Commit 29131b9

Browse files
committed
feature1:支持excel转换为PDF
1 parent 41a3f9b commit 29131b9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+995
-5
lines changed

doc/font/SimHei.ttf

9.6 MB
Binary file not shown.

fastexcel-core/pom.xml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
<name>fastexcel-core</name>
1717
<version>${revision}</version>
1818

19+
<properties>
20+
<itext.version>7.1.15</itext.version>
21+
</properties>
22+
1923
<dependencies>
2024
<dependency>
2125
<groupId>org.apache.commons</groupId>
@@ -61,5 +65,47 @@
6165
<artifactId>fastexcel-support</artifactId>
6266
<version>0.0.1</version>
6367
</dependency>
68+
<!-- itext7 -->
69+
<dependency>
70+
<groupId>com.itextpdf</groupId>
71+
<artifactId>itext7-core</artifactId>
72+
<version>${itext.version}</version>
73+
<type>pom</type>
74+
</dependency>
75+
<dependency>
76+
<groupId>com.itextpdf</groupId>
77+
<artifactId>kernel</artifactId>
78+
<version>${itext.version}</version>
79+
</dependency>
80+
<dependency>
81+
<groupId>com.itextpdf</groupId>
82+
<artifactId>io</artifactId>
83+
<version>${itext.version}</version>
84+
</dependency>
85+
<dependency>
86+
<groupId>com.itextpdf</groupId>
87+
<artifactId>layout</artifactId>
88+
<version>${itext.version}</version>
89+
</dependency>
90+
<dependency>
91+
<groupId>com.itextpdf</groupId>
92+
<artifactId>forms</artifactId>
93+
<version>${itext.version}</version>
94+
</dependency>
95+
<dependency>
96+
<groupId>com.itextpdf</groupId>
97+
<artifactId>pdfa</artifactId>
98+
<version>${itext.version}</version>
99+
</dependency>
100+
<dependency>
101+
<groupId>com.itextpdf</groupId>
102+
<artifactId>pdftest</artifactId>
103+
<version>${itext.version}</version>
104+
</dependency>
105+
<dependency>
106+
<groupId>com.itextpdf</groupId>
107+
<artifactId>font-asian</artifactId>
108+
<version>${itext.version}</version>
109+
</dependency>
64110
</dependencies>
65111
</project>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,29 @@
11
package cn.idev.excel;
22

3+
import cn.idev.excel.fileconvertor.ExcelConverter;
4+
import cn.idev.excel.fileconvertor.FileConverterContext;
5+
6+
import java.io.File;
7+
38
/**
49
* This is actually {@link FastExcelFactory}, and short names look better.
510
*
611
* @author jipengfei
712
*/
813
public class FastExcel extends FastExcelFactory {
914

15+
/**
16+
* Convert excel to pdf
17+
*
18+
* @param excelFile excel file
19+
* @param pdfFile pdf file
20+
* @param fontPath font path for pdf can be null
21+
* @param sheets sheet index to convert, if null convert all sheets
22+
*/
23+
public static void convertToPdf(File excelFile, File pdfFile, String fontPath, int[] sheets) {
24+
FileConverterContext context = new FileConverterContext(excelFile, pdfFile, fontPath, sheets);
25+
ExcelConverter excelConverter = context.getExcelConverter();
26+
excelConverter.convertToPdf();
27+
}
28+
1029
}

fastexcel-core/src/main/java/cn/idev/excel/FastExcelFactory.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,4 +353,25 @@ public static ExcelReaderSheetBuilder readSheet(Integer sheetNo, String sheetNam
353353
}
354354
return excelReaderSheetBuilder;
355355
}
356+
357+
/**
358+
* Build excel the 'readSheet'
359+
* @param sheetNo Index of sheet,0 base.
360+
* @param sheetName The name of sheet.
361+
* @param numRows The number of rows to read, the default is all, start with 0.
362+
* @return
363+
*/
364+
public static ExcelReaderSheetBuilder readSheet(Integer sheetNo, String sheetName,Integer numRows) {
365+
ExcelReaderSheetBuilder excelReaderSheetBuilder = new ExcelReaderSheetBuilder();
366+
if (sheetNo != null) {
367+
excelReaderSheetBuilder.sheetNo(sheetNo);
368+
}
369+
if (sheetName != null) {
370+
excelReaderSheetBuilder.sheetName(sheetName);
371+
}
372+
if (numRows !=null) {
373+
excelReaderSheetBuilder.numRows(numRows);
374+
}
375+
return excelReaderSheetBuilder;
376+
}
356377
}
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
package cn.idev.excel.fileconvertor;
2+
3+
import com.itextpdf.layout.element.Table;
4+
import com.itextpdf.layout.property.TextAlignment;
5+
import org.apache.poi.ss.usermodel.*;
6+
import org.apache.poi.ss.util.CellRangeAddress;
7+
8+
import java.io.IOException;
9+
import java.util.List;
10+
11+
public abstract class BaseExcelConverter implements ExcelConverter {
12+
13+
private final FileConverterContext context;
14+
15+
public BaseExcelConverter(FileConverterContext context) {
16+
this.context = context;
17+
}
18+
19+
@Override
20+
public void convertToPdf() {
21+
try {
22+
for (int sheetIndex : context.getSheets()) {
23+
processSheet(sheetIndex);
24+
}
25+
context.getDocument().close();
26+
} catch (Exception e) {
27+
throw new RuntimeException(e);
28+
}
29+
}
30+
31+
private void processSheet(int sheetIndex) throws IOException {
32+
Sheet sheet = context.getWorkbook().getSheetAt(sheetIndex);
33+
if (sheet == null || sheet.getRow(0) == null) {
34+
return;
35+
}
36+
float[] columnWidths = getColumnWidths(sheet);
37+
Table table = new Table(columnWidths);
38+
39+
addRowsToTable(table, sheet, columnWidths, context.getFountPath());
40+
// addPicsToTable(table, sheet);
41+
42+
context.getDocument().add(table);
43+
}
44+
45+
protected abstract void addPicsToTable(Table table, Sheet sheet);
46+
47+
private void addRowsToTable(Table table, Sheet sheet, float[] columnWidths, String fontPath) throws IOException {
48+
int lastRowNum = sheet.getLastRowNum() + 1;
49+
int lastCellNum = sheet.getRow(0).getLastCellNum();
50+
for (int i = 0; i < lastRowNum; i++) {
51+
Row row = sheet.getRow(i);
52+
addRowToTable(table, row, lastCellNum, columnWidths, fontPath);
53+
}
54+
}
55+
56+
private void addRowToTable(Table table, Row row, int lastCellNum, float[] columnWidths, String fontPath) throws IOException {
57+
if (row == null) {
58+
addEmptyCells(table, lastCellNum); // 0 for empty row
59+
return;
60+
}
61+
62+
for (int j = 0; j < lastCellNum; j++) {
63+
Cell cell = row.getCell(j);
64+
if (cell != null && !isCellProcessed(cell)) {
65+
// addCellToTable(table, cell, columnWidths, fontPath);
66+
CellRangeAddress cellRange = getCellRangeAddress(cell);
67+
int rowspan = (cellRange != null) ? (cellRange.getLastRow() - cellRange.getFirstRow() + 1) : 1;
68+
int colspan = (cellRange != null) ? (cellRange.getLastColumn() - cellRange.getFirstColumn() + 1) : 1;
69+
if ((cellRange != null)) {
70+
j = cellRange.getLastColumn();
71+
}
72+
float maxWidth = (cellRange != null) ? calculateMaxWidth(columnWidths, cellRange) : columnWidths[j];
73+
74+
com.itextpdf.layout.element.Cell pdfCell = convertCell(cell, rowspan, colspan, maxWidth, fontPath);
75+
table.addCell(pdfCell);
76+
} else if (cell == null) {
77+
addEmptyCell(table);
78+
}
79+
}
80+
}
81+
82+
private float calculateMaxWidth(float[] columnWidths, CellRangeAddress cellRange) {
83+
float maxWidth = 0;
84+
for (int k = cellRange.getFirstColumn(); k < cellRange.getLastColumn(); k++) {
85+
maxWidth += columnWidths[k];
86+
}
87+
return maxWidth;
88+
}
89+
90+
private void addEmptyCell(Table table) {
91+
com.itextpdf.layout.element.Cell pdfCell = new com.itextpdf.layout.element.Cell();
92+
pdfCell.setBorder(com.itextpdf.layout.borders.Border.NO_BORDER);
93+
table.addCell(pdfCell);
94+
}
95+
96+
private void addEmptyCells(Table table, int numberOfCells) {
97+
for (int j = 0; j < numberOfCells; j++) {
98+
addEmptyCell(table);
99+
}
100+
}
101+
102+
protected abstract com.itextpdf.layout.element.Cell convertCell(Cell cell, int rowspan, int colspan, float maxWidth, String fontPath) throws IOException;
103+
104+
public static com.itextpdf.layout.property.VerticalAlignment getVerticalAlignment(VerticalAlignment verticalAlignment) {
105+
switch (verticalAlignment) {
106+
case TOP:
107+
return com.itextpdf.layout.property.VerticalAlignment.TOP;
108+
case BOTTOM:
109+
return com.itextpdf.layout.property.VerticalAlignment.BOTTOM;
110+
case JUSTIFY:
111+
case CENTER:
112+
return com.itextpdf.layout.property.VerticalAlignment.MIDDLE;
113+
}
114+
return com.itextpdf.layout.property.VerticalAlignment.MIDDLE;
115+
}
116+
117+
public static TextAlignment getTextAlignment(org.apache.poi.ss.usermodel.HorizontalAlignment alignment, CellType cellType) {
118+
switch (alignment) {
119+
case LEFT:
120+
return TextAlignment.LEFT;
121+
case RIGHT:
122+
return TextAlignment.RIGHT;
123+
case CENTER:
124+
return TextAlignment.CENTER;
125+
case JUSTIFY:
126+
return TextAlignment.JUSTIFIED;
127+
case GENERAL:
128+
if (cellType == CellType.NUMERIC) {
129+
return TextAlignment.RIGHT;
130+
} else if (cellType == CellType.BOOLEAN) {
131+
return TextAlignment.CENTER;
132+
}
133+
}
134+
return TextAlignment.LEFT;
135+
}
136+
137+
private float[] getColumnWidths(Sheet sheet) {
138+
short lastCellNum = sheet.getRow(0).getLastCellNum();
139+
float[] widths = new float[lastCellNum];
140+
for (int i = 0; i < lastCellNum; i++) {
141+
widths[i] = sheet.getColumnWidthInPixels(i);
142+
}
143+
return widths;
144+
}
145+
146+
private boolean isCellProcessed(Cell cell) {
147+
List<CellRangeAddress> mergedRegions = cell.getSheet().getMergedRegions();
148+
int rowIndex = cell.getRowIndex();
149+
int columnIndex = cell.getColumnIndex();
150+
151+
for (CellRangeAddress cellAddresses : mergedRegions) {
152+
if (cellAddresses.getFirstRow() <= rowIndex && cellAddresses.getLastRow() >= rowIndex
153+
&& cellAddresses.getFirstColumn() <= columnIndex && cellAddresses.getLastColumn() >= columnIndex) {
154+
return !(cellAddresses.getFirstRow() == rowIndex && cellAddresses.getFirstColumn() == columnIndex);
155+
}
156+
}
157+
return false;
158+
}
159+
160+
private CellRangeAddress getCellRangeAddress(Cell cell) {
161+
List<CellRangeAddress> mergedRegions = cell.getSheet().getMergedRegions();
162+
int rowIndex = cell.getRowIndex();
163+
int columnIndex = cell.getColumnIndex();
164+
165+
for (CellRangeAddress cellAddresses : mergedRegions) {
166+
if (cellAddresses.getFirstRow() == rowIndex && cellAddresses.getFirstColumn() == columnIndex) {
167+
return cellAddresses;
168+
}
169+
}
170+
return null;
171+
}
172+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package cn.idev.excel.fileconvertor;
2+
3+
import org.apache.poi.ss.usermodel.Cell;
4+
import org.apache.poi.ss.usermodel.CellType;
5+
import org.apache.poi.ss.usermodel.DateUtil;
6+
import org.apache.poi.util.LocaleUtil;
7+
8+
import java.text.SimpleDateFormat;
9+
10+
public class Excel2PdfUtils {
11+
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; // 日期格式
12+
private static final String TRUE_STRING = "TRUE";
13+
private static final String FALSE_STRING = "FALSE";
14+
private static final String EMPTY_STRING = "";
15+
16+
// 使用单例模式确保 SimpleDateFormat 只被创建一次
17+
private static final ThreadLocal<SimpleDateFormat> DATE_FORMATTER = ThreadLocal.withInitial(() ->
18+
new SimpleDateFormat(DATE_FORMAT, LocaleUtil.getUserLocale())
19+
);
20+
21+
public static String getValue(Cell cell) {
22+
if (cell == null) {
23+
return EMPTY_STRING;
24+
}
25+
26+
CellType cellType = cell.getCellType();
27+
switch (cellType) {
28+
case BOOLEAN:
29+
return cell.getBooleanCellValue() ? TRUE_STRING : FALSE_STRING;
30+
case NUMERIC:
31+
return getNumericCellValue(cell);
32+
case STRING:
33+
return cell.getStringCellValue();
34+
default:
35+
return EMPTY_STRING;
36+
}
37+
}
38+
39+
private static String getNumericCellValue(Cell cell) {
40+
if (DateUtil.isCellDateFormatted(cell)) {
41+
return DATE_FORMATTER.get().format(cell.getDateCellValue());
42+
}
43+
return String.valueOf(cell.getNumericCellValue());
44+
}
45+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package cn.idev.excel.fileconvertor;
2+
3+
import java.io.File;
4+
5+
/**
6+
* Excel convert to other file
7+
* @author jipengfei
8+
*/
9+
public interface ExcelConverter {
10+
11+
/**
12+
* excel to pdf
13+
*
14+
*/
15+
void convertToPdf();
16+
17+
}

0 commit comments

Comments
 (0)