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+ }
0 commit comments