Skip to content

Commit 25819c6

Browse files
committed
优化Excel拆分工具。
1 parent 0cb54e0 commit 25819c6

4 files changed

Lines changed: 209 additions & 62 deletions

File tree

src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/ExcelSplitToolController.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,15 @@ public void initialize(URL location, ResourceBundle resources) {
2929
}
3030

3131
private void initView() {
32+
JavaFxViewUtil.setSpinnerValueFactory(sheetSelectSpinner, 0, Integer.MAX_VALUE, 0);
3233
JavaFxViewUtil.setSpinnerValueFactory(splitType1Spinner, 1, Integer.MAX_VALUE, 3);
3334
JavaFxViewUtil.setSpinnerValueFactory(splitType2Spinner, 1, Integer.MAX_VALUE, 10);
3435
}
3536

3637
private void initEvent() {
37-
selectFileTextField.setText("C:\\Users\\5FDSJ068\\Desktop\\address list20180411.xls");
38+
selectFileTextField.setText("C:\\Users\\5FDSJ068\\Desktop\\test/test.xlsx");
3839
FileChooserUtil.setOnDrag(selectFileTextField, FileChooserUtil.FileType.FILE);
40+
FileChooserUtil.setOnDrag(saveFilePathTextField, FileChooserUtil.FileType.FOLDER);
3941
}
4042

4143
private void initService() {
@@ -49,6 +51,14 @@ private void selectFileAction(ActionEvent event) {
4951
}
5052
}
5153

54+
@FXML
55+
private void saveFilePathAction(ActionEvent event) {
56+
File file = FileChooserUtil.chooseDirectory();
57+
if (file != null) {
58+
saveFilePathTextField.setText(file.getPath());
59+
}
60+
}
61+
5262
@FXML
5363
private void splitAction(ActionEvent event) {
5464
try {

src/main/java/com/xwintop/xJavaFxTool/services/littleTools/ExcelSplitToolService.java

Lines changed: 173 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import lombok.Getter;
55
import lombok.Setter;
66
import lombok.extern.slf4j.Slf4j;
7+
import org.apache.commons.lang3.StringUtils;
78
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
89
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
910
import org.apache.poi.ss.usermodel.Cell;
@@ -16,6 +17,8 @@
1617
import java.io.FileInputStream;
1718
import java.io.FileOutputStream;
1819
import java.io.IOException;
20+
import java.nio.file.Paths;
21+
import java.util.*;
1922

2023
@Getter
2124
@Setter
@@ -32,75 +35,39 @@ public void splitAction() throws Exception { //拆分表格
3235
FileInputStream fileInputStream = new FileInputStream(filePath);
3336

3437
Workbook workbook = null;
35-
if (filePath.endsWith(".xlsx")) {
36-
workbook = new XSSFWorkbook(fileInputStream);
37-
} else if (filePath.endsWith(".xls")) {
38+
if (filePath.endsWith(".xls")) {
3839
POIFSFileSystem fileSystem = new POIFSFileSystem(fileInputStream);
3940
workbook = new HSSFWorkbook(fileSystem);
41+
} else if (filePath.endsWith(".xlsx")) {
42+
workbook = new XSSFWorkbook(fileInputStream);
4043
} else {
4144
throw new RuntimeException("错误提示: 您设置的Excel文件名不合法!");
4245
}
43-
Sheet sheet = workbook.getSheetAt(0);
46+
Sheet sheet = workbook.getSheetAt(excelSplitToolController.getSheetSelectSpinner().getValue());
4447
int lastRowIndex = sheet.getLastRowNum();// 行数
4548
log.info("读取到Excel文件行数:" + lastRowIndex);
4649
int splitNumber = 0;
50+
String newFilePath = StringUtils.appendIfMissing(filePath, "", ".xls", ".xlsx");
51+
if (StringUtils.isNotEmpty(excelSplitToolController.getSaveFilePathTextField().getText())) {
52+
newFilePath = StringUtils.appendIfMissing(excelSplitToolController.getSaveFilePathTextField().getText(), "/", "/", "\\") + Paths.get(newFilePath).getFileName();
53+
}
4754
if (excelSplitToolController.getSplitType1RadioButton().isSelected()) {
4855
splitNumber = lastRowIndex / (excelSplitToolController.getSplitType1Spinner().getValue() - 1);
56+
saveSplitWorkbook(sheet, splitNumber, newFilePath);
4957
} else if (excelSplitToolController.getSplitType2RadioButton().isSelected()) {
5058
splitNumber = excelSplitToolController.getSplitType2Spinner().getValue();
59+
saveSplitWorkbook(sheet, splitNumber, newFilePath);
5160
} else if (excelSplitToolController.getSplitType3RadioButton().isSelected()) {
52-
53-
}
54-
Workbook newWorkbook = null;
55-
if (excelSplitToolController.getOutputType1RadioButton().isSelected()) {
56-
newWorkbook = new HSSFWorkbook();
57-
} else {
58-
newWorkbook = new XSSFWorkbook();
59-
}
60-
Sheet newSheet = newWorkbook.createSheet();
61-
int addRowIndex = 0;
62-
for (int i = 0; i <= lastRowIndex; i++) {
63-
Row row = newSheet.createRow(addRowIndex++);
64-
sheet.getRow(i).cellIterator().forEachRemaining(cell -> {
65-
setCellValue(cell, row.createCell(cell.getColumnIndex(), cell.getCellType()));
66-
});
67-
if (addRowIndex == splitNumber) {
68-
FileOutputStream out = null;
69-
try {
70-
out = new FileOutputStream(new File(new File(filePath).getParent(), "newExcel" + Math.random() + ".xls"));
71-
newWorkbook.write(out);
72-
} catch (IOException e) {
73-
System.out.println(e.toString());
74-
} finally {
75-
try {
76-
out.close();
77-
} catch (IOException e) {
78-
System.out.println(e.toString());
79-
}
80-
}
81-
addRowIndex = 0;
82-
if (excelSplitToolController.getOutputType1RadioButton().isSelected()) {
83-
newWorkbook = new HSSFWorkbook();
84-
} else {
85-
newWorkbook = new XSSFWorkbook();
86-
}
87-
newSheet = newWorkbook.createSheet();
61+
String splitType3String = excelSplitToolController.getSplitType3TextField().getText();
62+
String[] splitCellIndex = null;
63+
if (StringUtils.isEmpty(splitType3String)) {
64+
splitCellIndex = new String[]{"0"};
65+
} else {
66+
splitCellIndex = splitType3String.split(",");
8867
}
68+
saveSplitWorkbook(sheet, newFilePath, splitCellIndex);
8969
}
9070

91-
FileOutputStream out = null;
92-
try {
93-
out = new FileOutputStream(new File(new File(filePath).getParent(), "newExcel" + Math.random() + ".xls"));
94-
newWorkbook.write(out);
95-
} catch (IOException e) {
96-
System.out.println(e.toString());
97-
} finally {
98-
try {
99-
out.close();
100-
} catch (IOException e) {
101-
System.out.println(e.toString());
102-
}
103-
}
10471
// for (int i = 0; i <= lastRowIndex; i++) {
10572
// Row row = sheet.getRow(i);
10673
// if (row == null) {
@@ -136,7 +103,134 @@ public void splitAction() throws Exception { //拆分表格
136103
// }
137104
}
138105

106+
private void saveSplitWorkbook(Sheet sheet, int splitNumber, String newFilePath) throws Exception {
107+
Workbook newWorkbook = null;
108+
int addRowIndex = 0;
109+
int saveFileIndex = 0;
110+
Iterator<Row> iterator = sheet.rowIterator();
111+
boolean isAddHead = excelSplitToolController.getIncludeHandCheckBox().isSelected();
112+
while (iterator.hasNext()) {
113+
if (newWorkbook == null) {
114+
if (excelSplitToolController.getOutputType1RadioButton().isSelected()) {
115+
newWorkbook = new HSSFWorkbook();
116+
} else {
117+
newWorkbook = new XSSFWorkbook();
118+
}
119+
}
120+
Sheet newSheet = null;
121+
if (newWorkbook.sheetIterator().hasNext()) {
122+
newSheet = newWorkbook.getSheetAt(0);
123+
} else {
124+
newSheet = newWorkbook.createSheet();
125+
if (isAddHead && saveFileIndex != 0) {
126+
Row newRow = newSheet.createRow(addRowIndex++);
127+
Row row = sheet.getRow(0);
128+
copyRow(row, newRow);
129+
}
130+
}
131+
Row row = iterator.next();
132+
Row newRow = newSheet.createRow(addRowIndex++);
133+
copyRow(row, newRow);
134+
if ((addRowIndex - splitNumber) == (isAddHead ? 1 : 0)) {
135+
saveFile(newWorkbook, newFilePath + "-" + (saveFileIndex++));
136+
newWorkbook.close();
137+
newWorkbook = null;
138+
addRowIndex = 0;
139+
}
140+
}
141+
if (newWorkbook != null) {
142+
saveFile(newWorkbook, newFilePath + "-" + saveFileIndex);
143+
newWorkbook.close();
144+
}
145+
}
146+
147+
private void saveSplitWorkbook(Sheet sheet, String newFilePath, String[] splitCellIndex) throws Exception {
148+
Map<String, List<Row>> rowMap = new HashMap<>();
149+
Iterator<Row> iterator = sheet.rowIterator();
150+
while (iterator.hasNext()) {
151+
Row row = iterator.next();
152+
String rowString = "";
153+
for (String cellIndex : splitCellIndex) {
154+
Cell cell = row.getCell(Integer.valueOf(cellIndex));
155+
rowString += getCellValue(cell);
156+
}
157+
if (rowMap.containsKey(rowString)) {
158+
rowMap.get(rowString).add(row);
159+
} else {
160+
List<Row> rowList = new ArrayList<>();
161+
rowList.add(row);
162+
rowMap.put(rowString, rowList);
163+
}
164+
}
165+
for (Map.Entry<String, List<Row>> stringListEntry : rowMap.entrySet()) {
166+
String key = stringListEntry.getKey();
167+
List<Row> rows = stringListEntry.getValue();
168+
Workbook newWorkbook = null;
169+
if (excelSplitToolController.getOutputType1RadioButton().isSelected()) {
170+
newWorkbook = new HSSFWorkbook();
171+
} else {
172+
newWorkbook = new XSSFWorkbook();
173+
}
174+
Sheet newSheet = newWorkbook.createSheet();
175+
int addRowIndex = 0;
176+
if (excelSplitToolController.getIncludeHandCheckBox().isSelected()) {
177+
Row newRow = newSheet.createRow(addRowIndex++);
178+
copyRow(sheet.getRow(0), newRow);
179+
}
180+
for (Row row : rows) {
181+
Row newRow = newSheet.createRow(addRowIndex++);
182+
copyRow(row, newRow);
183+
}
184+
saveFile(newWorkbook, newFilePath + "-" + key);
185+
if (newWorkbook != null) {
186+
newWorkbook.close();
187+
}
188+
}
189+
190+
}
191+
192+
public static void saveFile(Workbook workbook, String filePath) {
193+
if (workbook instanceof HSSFWorkbook) {
194+
filePath = StringUtils.appendIfMissing(filePath, ".xls", ".xls", ".xlsx");
195+
} else if (workbook instanceof XSSFWorkbook) {
196+
filePath = StringUtils.appendIfMissing(filePath, ".xlsx", ".xls", ".xlsx");
197+
}
198+
FileOutputStream out = null;
199+
try {
200+
out = new FileOutputStream(new File(filePath));
201+
workbook.write(out);
202+
} catch (IOException e) {
203+
System.out.println(e.toString());
204+
} finally {
205+
try {
206+
if (out != null) {
207+
out.close();
208+
}
209+
} catch (IOException e) {
210+
log.error("FileOutputStream close Fail" + e.getMessage());
211+
}
212+
}
213+
}
214+
215+
public static void copyRow(Row row, Row newRow) {
216+
try {
217+
newRow.setHeight(row.getHeight());
218+
newRow.setHeightInPoints(row.getHeightInPoints());
219+
newRow.setZeroHeight(row.getZeroHeight());
220+
newRow.setRowStyle(row.getRowStyle());
221+
} catch (Exception e) {
222+
223+
}
224+
row.cellIterator().forEachRemaining(cell -> {
225+
setCellValue(cell, newRow.createCell(cell.getColumnIndex(), cell.getCellType()));
226+
});
227+
}
228+
139229
public static void setCellValue(Cell cell, Cell newCell) {
230+
try {
231+
newCell.setCellStyle(cell.getCellStyle());
232+
} catch (Exception e) {
233+
}
140234
// 以下是判断数据的类型
141235
switch (cell.getCellType()) {
142236
case BLANK:// 空值
@@ -146,7 +240,7 @@ public static void setCellValue(Cell cell, Cell newCell) {
146240
newCell.setCellValue(cell.getBooleanCellValue());// 布尔型
147241
break;
148242
case FORMULA:
149-
newCell.setCellValue(cell.getCellFormula());// 公式型
243+
newCell.setCellFormula(cell.getCellFormula());// 公式型
150244
break;
151245
case NUMERIC:
152246
newCell.setCellValue(cell.getNumericCellValue());// 数值型
@@ -159,4 +253,29 @@ public static void setCellValue(Cell cell, Cell newCell) {
159253
break;
160254
}
161255
}
256+
257+
public static String getCellValue(Cell cell) {
258+
String str = null;
259+
switch (cell.getCellType()) {
260+
case BLANK:// 空值
261+
str = "";
262+
break;
263+
case BOOLEAN:
264+
str = String.valueOf(cell.getBooleanCellValue());// 布尔型
265+
break;
266+
case FORMULA:
267+
str = cell.getCellFormula();// 公式型
268+
break;
269+
case NUMERIC:
270+
str = String.valueOf(cell.getNumericCellValue());// 数值型
271+
break;
272+
case STRING:
273+
str = String.valueOf(cell.getStringCellValue());// 字符型
274+
break;
275+
default:
276+
str = null;
277+
break;
278+
}
279+
return str;
280+
}
162281
}

src/main/java/com/xwintop/xJavaFxTool/view/littleTools/ExcelSplitToolView.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public abstract class ExcelSplitToolView implements Initializable {
1212
@FXML
1313
protected TextField selectFileTextField;
1414
@FXML
15+
protected Spinner<Integer> sheetSelectSpinner;
16+
@FXML
1517
protected Button selectFileButton;
1618
@FXML
1719
protected CheckBox includeHandCheckBox;
@@ -35,5 +37,10 @@ public abstract class ExcelSplitToolView implements Initializable {
3537
protected Button splitButton;
3638
@FXML
3739
protected RadioButton splitType3RadioButton;
38-
40+
@FXML
41+
protected TextField splitType3TextField;
42+
@FXML
43+
protected TextField saveFilePathTextField;
44+
@FXML
45+
protected Button saveFilePathButton;
3946
}

src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/ExcelSplitTool.fxml

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,17 @@
77
<?import javafx.scene.control.Spinner?>
88
<?import javafx.scene.control.TextField?>
99
<?import javafx.scene.control.ToggleGroup?>
10+
<?import javafx.scene.control.Tooltip?>
1011
<?import javafx.scene.layout.AnchorPane?>
1112

12-
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.xwintop.xJavaFxTool.controller.littleTools.ExcelSplitToolController">
13+
<AnchorPane prefHeight="400.0" prefWidth="702.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.xwintop.xJavaFxTool.controller.littleTools.ExcelSplitToolController">
1314
<children>
1415
<Label layoutX="31.0" layoutY="24.0" text="文件选择:" />
1516
<TextField fx:id="selectFileTextField" layoutX="99.0" layoutY="20.0" />
1617
<Button fx:id="selectFileButton" layoutX="256.0" layoutY="20.0" mnemonicParsing="false" onAction="#selectFileAction" text="选择" />
17-
<Label layoutX="31.0" layoutY="66.0" text="文件分隔方式:" />
18-
<CheckBox fx:id="includeHandCheckBox" layoutX="31.0" layoutY="100.0" mnemonicParsing="false" text="Excel包含标题行" />
19-
<RadioButton fx:id="splitType1RadioButton" layoutX="34.0" layoutY="131.0" mnemonicParsing="false" selected="true" text="按平均分成">
18+
<Label layoutX="31.0" layoutY="82.0" text="文件分隔方式:" />
19+
<CheckBox fx:id="includeHandCheckBox" layoutX="31.0" layoutY="107.0" mnemonicParsing="false" text="Excel包含标题行" />
20+
<RadioButton fx:id="splitType1RadioButton" layoutX="33.0" layoutY="132.0" mnemonicParsing="false" selected="true" text="按平均分成">
2021
<toggleGroup>
2122
<ToggleGroup fx:id="splitTypeToggleGroup" />
2223
</toggleGroup>
@@ -33,7 +34,17 @@
3334
</toggleGroup>
3435
</RadioButton>
3536
<RadioButton fx:id="outputType2RadioButton" layoutX="125.0" layoutY="212.0" mnemonicParsing="false" text="xlsx格式" toggleGroup="$outputTypeToggleGroup" />
36-
<Button fx:id="splitButton" layoutX="29.0" layoutY="247.0" mnemonicParsing="false" onAction="#splitAction" text="开始分隔" />
37-
<RadioButton fx:id="splitType3RadioButton" layoutX="436.0" layoutY="133.0" mnemonicParsing="false" text="按列分类拆分" toggleGroup="$splitTypeToggleGroup" />
37+
<Button fx:id="splitButton" layoutX="29.0" layoutY="282.0" mnemonicParsing="false" onAction="#splitAction" text="开始分隔" />
38+
<RadioButton fx:id="splitType3RadioButton" layoutX="33.0" layoutY="161.0" mnemonicParsing="false" text="按列分类拆分" toggleGroup="$splitTypeToggleGroup" />
39+
<TextField fx:id="splitType3TextField" layoutX="141.0" layoutY="158.0" promptText="列数(默认为0)">
40+
<tooltip>
41+
<Tooltip text="列数从0开始,多个组合可用,分割" />
42+
</tooltip>
43+
</TextField>
44+
<Label layoutX="28.0" layoutY="252.0" text="输出文件夹:" />
45+
<TextField fx:id="saveFilePathTextField" layoutX="100.0" layoutY="248.0" promptText="留空为原文件同目录" />
46+
<Button fx:id="saveFilePathButton" layoutX="253.0" layoutY="248.0" mnemonicParsing="false" onAction="#saveFilePathAction" text="选择" />
47+
<Label layoutX="31.0" layoutY="51.0" text="Sheet选择:" />
48+
<Spinner fx:id="sheetSelectSpinner" layoutX="100.0" layoutY="47.0" prefHeight="23.0" prefWidth="81.0" />
3849
</children>
3950
</AnchorPane>

0 commit comments

Comments
 (0)