From 90da11688f1b984397c2ce72c8a0a38e260a4431 Mon Sep 17 00:00:00 2001
From: felixnan168
Date: Tue, 19 Dec 2023 15:14:41 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=96=87=E4=BB=B6=E6=A0=BC?=
=?UTF-8?q?=E5=BC=8F=E5=8C=96=E5=B7=A5=E5=85=B7=E3=80=81PDF=E6=8B=86?=
=?UTF-8?q?=E5=88=86/=E5=90=88=E5=B9=B6=E5=B7=A5=E5=85=B7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.idea/icon.png | Bin 1483 -> 0 bytes
MooTool.l4j.ini | 3 -
pom.xml | 28 +-
.../moo/tool/ui/form/MainWindow.form | 20 +
.../moo/tool/ui/form/MainWindow.java | 13 +
.../ui/form/func/FileReformattingForm.form | 112 +++
.../ui/form/func/FileReformattingForm.java | 114 +++
.../moo/tool/ui/form/func/PdfForm.form | 126 +++
.../moo/tool/ui/form/func/PdfForm.java | 752 ++++++++++++++++++
.../listener/func/FileReformatListener.java | 190 +++++
.../ui/listener/func/PDFMergerListener.java | 379 +++++++++
.../ui/listener/func/PDFSplitterListener.java | 495 ++++++++++++
.../moo/tool/util/FileReformatUtil.java | 88 ++
.../moo/tool/util/XmlReformatUtil.java | 61 ++
src/main/resources/icon/gear.svg | 28 +
src/main/resources/icon/pdf.svg | 13 +
16 files changed, 2416 insertions(+), 6 deletions(-)
delete mode 100644 .idea/icon.png
delete mode 100644 MooTool.l4j.ini
create mode 100755 src/main/java/com/luoboduner/moo/tool/ui/form/func/FileReformattingForm.form
create mode 100755 src/main/java/com/luoboduner/moo/tool/ui/form/func/FileReformattingForm.java
create mode 100755 src/main/java/com/luoboduner/moo/tool/ui/form/func/PdfForm.form
create mode 100755 src/main/java/com/luoboduner/moo/tool/ui/form/func/PdfForm.java
create mode 100755 src/main/java/com/luoboduner/moo/tool/ui/listener/func/FileReformatListener.java
create mode 100755 src/main/java/com/luoboduner/moo/tool/ui/listener/func/PDFMergerListener.java
create mode 100755 src/main/java/com/luoboduner/moo/tool/ui/listener/func/PDFSplitterListener.java
create mode 100755 src/main/java/com/luoboduner/moo/tool/util/FileReformatUtil.java
create mode 100755 src/main/java/com/luoboduner/moo/tool/util/XmlReformatUtil.java
create mode 100755 src/main/resources/icon/gear.svg
create mode 100755 src/main/resources/icon/pdf.svg
diff --git a/.idea/icon.png b/.idea/icon.png
deleted file mode 100644
index f9088c365e5ef6b375a1668c68610743f9790580..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1483
zcmV;+1vL7JP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA1vE)SK~z{rbNPHnwqiqvg0ud`JQv5+8Y9!PqXlfI!nrMl}
zKT3Rrlqjt)5)nv^T8%-arAlbG(o)JxN=tXQJG(o(<9B9hR!j~NL7F$WXSbt)ENR%T{0h(*NxX#I$X&_-$g
zY%r|=5b!Y9l`H1LhKAxz-d_9K@gTnlBT=VQ8dzK?{@!-R94;g+0{`?
zsT!UZ94Cj?tQl@<-p_Kt%4zsMk|8kbA{+w{S$Fbqr9m}3aCKf<|MGa3tOMva;
z{kgY}`S@bh*MtdA6a;};EEc72gcDuPr|auHo6*gN2tFQ-BS`?IAC~^(57`f>p%ic&
z$I8}4!MX?E8a1vm>n??89a+TYtZ3B*b*AJ#*LoPZ!>W=evkUjVG@O1}t)jdCJOH
ze0lAf*`tOhK;$p(xXdcbylNyFt%r(P)4TKW9PM3)lhb?PKxb7(M&vXe6{OhI448jA
z;mQNKX8PCNH?B)gsC=-Gt-Cj%da3aFc+bnbJx`(Q1{YmwlL8Q+Y*-I{bJI$+DY>NV
zZm1YiJ$+PH4k>f>(ADkSJm9qzP`1fW%zz?b;H+Kq;IUYEwxno8_4MIcJc_#^DX~e2
zM7WH-?-xD{kq&z4#F^B$T^&hXdx9*}O*_+T-}o}@J7c9{bfAk;m;^`nd?3K#s!c^C
z5@vn{M?Ci%4mTo$7J1J+J4pH=8q*Iq`bd$IZooBPJ{Jp&Of+iThuGh^4Dn
zuj+_KIhz{R02N~Zg2jnym!ueoX-TQBlU#|V$t65<>Z8p$6X^(;)smOg^c>f
zX?MFLU3I&>H5CyE{+1YSr)!fi9k9OZ}}oUl{m2KR0qHVI656^A~Xdg
z0s^Q|6;p*NhZYUNh-glKPXF&<>_2z0^amV)JL~`e002ovPDHLkV1nWx;-clr-!SL<
lmqC@+PA)Q9p8wB5^e@GPVX#d0zG(me002ovPDHLkV1hJEyo&$;
diff --git a/MooTool.l4j.ini b/MooTool.l4j.ini
deleted file mode 100644
index 07b954e9..00000000
--- a/MooTool.l4j.ini
+++ /dev/null
@@ -1,3 +0,0 @@
--Dswing.aatext=true
--XX:+UseZGC
--XX:+ZGenerational
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index a43ea094..15fb5ffd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -15,10 +15,10 @@
UTF-8
UTF-8
- 21
- 21
+ 17
+ 17
- 21
+ 17
1.4.11
5.1.1
5.8.22
@@ -46,6 +46,9 @@
1.2.0
1.5.0
4.0.15
+ 1.16.2
+ 1.5rc3
+ 5.5.1
@@ -268,6 +271,25 @@
${groovy.version}
+
+ org.jsoup
+ jsoup
+ ${jsoup.version}
+
+
+
+ jalopy
+ jalopy
+ ${jalopy.version}
+
+
+
+ com.itextpdf
+ itextpdf
+ ${itextpdf.version}
+ jar
+
+
diff --git a/src/main/java/com/luoboduner/moo/tool/ui/form/MainWindow.form b/src/main/java/com/luoboduner/moo/tool/ui/form/MainWindow.form
index 3df34a06..aaae8d6b 100644
--- a/src/main/java/com/luoboduner/moo/tool/ui/form/MainWindow.form
+++ b/src/main/java/com/luoboduner/moo/tool/ui/form/MainWindow.form
@@ -163,6 +163,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/com/luoboduner/moo/tool/ui/form/MainWindow.java b/src/main/java/com/luoboduner/moo/tool/ui/form/MainWindow.java
index c155251c..0649027f 100644
--- a/src/main/java/com/luoboduner/moo/tool/ui/form/MainWindow.java
+++ b/src/main/java/com/luoboduner/moo/tool/ui/form/MainWindow.java
@@ -40,6 +40,8 @@ public class MainWindow {
private JPanel regexPanel;
private JPanel imagePanel;
private JPanel javaConsolePanel;
+ private JPanel reformattingPanel;
+ private JPanel pdfPanel;
private static MainWindow mainWindow;
@@ -78,6 +80,8 @@ public class MainWindow {
mainWindow.getTabbedPane().setIconAt(13, new FlatSVGIcon("icon/schedule.svg", 15, 15));
mainWindow.getTabbedPane().setIconAt(14, new FlatSVGIcon("icon/reg.svg"));
mainWindow.getTabbedPane().setIconAt(15, new FlatSVGIcon("icon/java.svg"));
+ mainWindow.getTabbedPane().setIconAt(16, new FlatSVGIcon("icon/gear.svg", 15, 15));
+ mainWindow.getTabbedPane().setIconAt(17, new FlatSVGIcon("icon/pdf.svg", 15, 15));
mainWindow.getQuickNotePanel().add(QuickNoteForm.getInstance().getQuickNotePanel(), gridConstraints);
mainWindow.getJsonBeautyPanel().add(JsonBeautyForm.getInstance().getJsonBeautyPanel(), gridConstraints);
@@ -95,6 +99,8 @@ public class MainWindow {
mainWindow.getRegexPanel().add(RegexForm.getInstance().getRegexPanel(), gridConstraints);
mainWindow.getImagePanel().add(ImageForm.getInstance().getImagePanel(), gridConstraints);
mainWindow.getJavaConsolePanel().add(JavaConsoleForm.getInstance().getJavaConsolePanel(), gridConstraints);
+ mainWindow.getReformattingPanel().add(FileReformattingForm.getInstance().getReformattingPanel(), gridConstraints);
+ mainWindow.getPdfPanel().add(PdfForm.getInstance().getPdfPanel(), gridConstraints);
mainWindow.getMainPanel().updateUI();
TabListener.addListeners();
@@ -168,6 +174,13 @@ public class MainWindow {
javaConsolePanel = new JPanel();
javaConsolePanel.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1));
tabbedPane.addTab("Java", javaConsolePanel);
+ reformattingPanel = new JPanel();
+ reformattingPanel.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1));
+ reformattingPanel.setToolTipText("格式化");
+ tabbedPane.addTab("格式化", reformattingPanel);
+ pdfPanel = new JPanel();
+ pdfPanel.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1));
+ tabbedPane.addTab("PDF", pdfPanel);
}
/**
diff --git a/src/main/java/com/luoboduner/moo/tool/ui/form/func/FileReformattingForm.form b/src/main/java/com/luoboduner/moo/tool/ui/form/func/FileReformattingForm.form
new file mode 100755
index 00000000..552ad976
--- /dev/null
+++ b/src/main/java/com/luoboduner/moo/tool/ui/form/func/FileReformattingForm.form
@@ -0,0 +1,112 @@
+
+
diff --git a/src/main/java/com/luoboduner/moo/tool/ui/form/func/FileReformattingForm.java b/src/main/java/com/luoboduner/moo/tool/ui/form/func/FileReformattingForm.java
new file mode 100755
index 00000000..3337d41d
--- /dev/null
+++ b/src/main/java/com/luoboduner/moo/tool/ui/form/func/FileReformattingForm.java
@@ -0,0 +1,114 @@
+package com.luoboduner.moo.tool.ui.form.func;
+
+import com.intellij.uiDesigner.core.GridConstraints;
+import com.intellij.uiDesigner.core.GridLayoutManager;
+import com.intellij.uiDesigner.core.Spacer;
+import com.luoboduner.moo.tool.ui.listener.func.FileReformatListener;
+import lombok.Getter;
+
+import javax.swing.*;
+import java.awt.*;
+
+@Getter
+public class FileReformattingForm {
+ private JPanel reformattingPanel;
+ private JComboBox fileType;
+ private JComboBox spaceNum;
+ private JTextArea resultArea;
+ private JButton uploadFile;
+ private JButton reformat;
+ private JLabel selectFileName;
+
+ private static FileReformattingForm fileReformattingForm;
+
+ public static FileReformattingForm getInstance() {
+ if (null == fileReformattingForm) {
+ fileReformattingForm = new FileReformattingForm();
+ }
+ return fileReformattingForm;
+ }
+
+ private FileReformattingForm() {
+ init();
+ }
+
+ private void init() {
+ FileReformatListener.ParameterBuilder.builder()
+ .buildFileType(this.fileType)
+ .buildSpaceNum(this.spaceNum)
+ .buildResultPanel(this.resultArea)
+ .buildUploadBtn(this.uploadFile)
+ .buildReformatBtn(this.reformat)
+ .buildSelectFileLabel(this.selectFileName)
+ .start();
+ }
+
+ {
+// GUI initializer generated by IntelliJ IDEA GUI Designer
+// >>> IMPORTANT!! <<<
+// DO NOT EDIT OR ADD ANY CODE HERE!
+ $$$setupUI$$$();
+ }
+
+ /**
+ * Method generated by IntelliJ IDEA GUI Designer
+ * >>> IMPORTANT!! <<<
+ * DO NOT edit this method OR call it in your code!
+ *
+ * @noinspection ALL
+ */
+ private void $$$setupUI$$$() {
+ reformattingPanel = new JPanel();
+ reformattingPanel.setLayout(new GridLayoutManager(2, 1, new Insets(15, 15, 15, 15), -1, -1));
+ final JPanel panel1 = new JPanel();
+ panel1.setLayout(new GridLayoutManager(2, 8, new Insets(0, 0, 0, 0), -1, -1));
+ reformattingPanel.add(panel1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
+ final JLabel label1 = new JLabel();
+ label1.setText("文件类型");
+ panel1.add(label1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+ final Spacer spacer1 = new Spacer();
+ panel1.add(spacer1, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
+ fileType = new JComboBox();
+ final DefaultComboBoxModel defaultComboBoxModel1 = new DefaultComboBoxModel();
+ defaultComboBoxModel1.addElement("XML");
+ defaultComboBoxModel1.addElement("HTML");
+ defaultComboBoxModel1.addElement("JAVA");
+ fileType.setModel(defaultComboBoxModel1);
+ panel1.add(fileType, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+ final JLabel label2 = new JLabel();
+ label2.setText("空格数量");
+ panel1.add(label2, new GridConstraints(0, 2, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+ spaceNum = new JComboBox();
+ final DefaultComboBoxModel defaultComboBoxModel2 = new DefaultComboBoxModel();
+ defaultComboBoxModel2.addElement("2");
+ defaultComboBoxModel2.addElement("3");
+ defaultComboBoxModel2.addElement("4");
+ defaultComboBoxModel2.addElement("5");
+ defaultComboBoxModel2.addElement("6");
+ spaceNum.setModel(defaultComboBoxModel2);
+ panel1.add(spaceNum, new GridConstraints(0, 3, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+ uploadFile = new JButton();
+ uploadFile.setText("选择文件");
+ panel1.add(uploadFile, new GridConstraints(0, 4, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+ reformat = new JButton();
+ reformat.setText("格式化");
+ panel1.add(reformat, new GridConstraints(0, 7, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+ selectFileName = new JLabel();
+ selectFileName.setText("");
+ panel1.add(selectFileName, new GridConstraints(0, 5, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+ final Spacer spacer2 = new Spacer();
+ panel1.add(spacer2, new GridConstraints(0, 6, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false));
+ final JScrollPane scrollPane1 = new JScrollPane();
+ reformattingPanel.add(scrollPane1, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
+ resultArea = new JTextArea();
+ scrollPane1.setViewportView(resultArea);
+ }
+
+ /**
+ * @noinspection ALL
+ */
+ public JComponent $$$getRootComponent$$$() {
+ return reformattingPanel;
+ }
+
+}
diff --git a/src/main/java/com/luoboduner/moo/tool/ui/form/func/PdfForm.form b/src/main/java/com/luoboduner/moo/tool/ui/form/func/PdfForm.form
new file mode 100755
index 00000000..08cb6991
--- /dev/null
+++ b/src/main/java/com/luoboduner/moo/tool/ui/form/func/PdfForm.form
@@ -0,0 +1,126 @@
+
+
diff --git a/src/main/java/com/luoboduner/moo/tool/ui/form/func/PdfForm.java b/src/main/java/com/luoboduner/moo/tool/ui/form/func/PdfForm.java
new file mode 100755
index 00000000..2212a277
--- /dev/null
+++ b/src/main/java/com/luoboduner/moo/tool/ui/form/func/PdfForm.java
@@ -0,0 +1,752 @@
+package com.luoboduner.moo.tool.ui.form.func;
+
+import com.formdev.flatlaf.extras.FlatSVGIcon;
+import com.intellij.uiDesigner.core.GridConstraints;
+import com.intellij.uiDesigner.core.GridLayoutManager;
+import com.intellij.uiDesigner.core.Spacer;
+import com.luoboduner.moo.tool.ui.listener.func.PDFMergerListener;
+import com.luoboduner.moo.tool.ui.listener.func.PDFSplitterListener;
+import lombok.Getter;
+
+import javax.swing.*;
+import javax.swing.border.TitledBorder;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.table.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.io.File;
+import java.util.LinkedList;
+import java.util.List;
+
+@Getter
+public class PdfForm {
+ private JPanel pdfPanel;
+ private JButton startTask;
+ private JButton newTask;
+ private JPanel taskPane;
+ private JPanel splitPane;
+ private JLabel helpBtn;
+ private JPanel mergePane;
+ private JButton startMerge;
+ private JButton addFile;
+ private JLabel helpMerge;
+ private JPanel filePane;
+
+ private static PdfForm instance;
+ private PDFSplitterListener listener;
+ private PDFMergerListener mergerListener;
+
+ private PdfForm() {
+ $$$setupUI$$$();
+ initSplitContent();
+ initMergeContent();
+ }
+
+ public static PdfForm getInstance() {
+ if (null == instance) {
+ synchronized (PdfForm.class) {
+ if (null == instance) {
+ instance = new PdfForm();
+ }
+ }
+ }
+ return instance;
+ }
+
+ private void initMergeContent() {
+ FileTableModel fileTableModel = new FileTableModel(10);
+ JTable table = new JTable(fileTableModel);
+ PDFTableModel.CommonComponentRenderer componentRenderer = fileTableModel.new CommonComponentRenderer();
+ table.setDefaultRenderer(JCheckBox.class, componentRenderer);
+ table.setDefaultRenderer(JButton.class, componentRenderer);
+ table.setDefaultRenderer(JTextField.class, componentRenderer);
+ table.setDefaultRenderer(JProgressBar.class, componentRenderer);
+ table.setDefaultRenderer(JLabel.class, componentRenderer);
+
+ table.setDefaultEditor(JTextField.class, fileTableModel.new CommonTextFieldEditor());
+ table.setDefaultEditor(JCheckBox.class, fileTableModel.new CommonCheckBoxEditor());
+ table.setDefaultEditor(JButton.class, fileTableModel.new CommonUploadEditor());
+
+ table.setRowHeight(30);
+ table.setRowMargin(5);
+ JTableHeader jTableHeader = table.getTableHeader();
+
+ table.getColumnModel().getColumn(0).setMaxWidth(100);
+ table.getColumnModel().getColumn(1).setMaxWidth(250);
+ table.getColumnModel().getColumn(1).setMinWidth(250);
+ table.getColumnModel().getColumn(5).setMaxWidth(200);
+
+ getFilePane().add(jTableHeader, BorderLayout.NORTH);
+ getFilePane().add(table, BorderLayout.CENTER);
+
+ mergerListener = new PDFMergerListener(getFilePane(), fileTableModel);
+ mergerListener.setComponents(fileTableModel.getComps());
+ mergerListener.setStartMerge(getStartMerge());
+ mergerListener.setHelpMerge(getHelpMerge());
+ mergerListener.setAddFile(getAddFile());
+ mergerListener.startListener();
+
+ getHelpMerge().setIcon(new FlatSVGIcon("icon/help.svg"));
+ }
+
+ private void initSplitContent() {
+ SplitTableModel taskTableModel = new SplitTableModel(10);
+ JTable table = new JTable(taskTableModel);
+ SplitTableModel.CommonComponentRenderer testRenderer = taskTableModel.new CommonComponentRenderer();
+ table.setDefaultRenderer(JCheckBox.class, testRenderer);
+ table.setDefaultRenderer(JButton.class, testRenderer);
+ table.setDefaultRenderer(JTextField.class, testRenderer);
+ table.setDefaultRenderer(JComboBox.class, testRenderer);
+ table.setDefaultRenderer(JProgressBar.class, testRenderer);
+ table.setDefaultRenderer(JLabel.class, testRenderer);
+
+ table.setDefaultEditor(JCheckBox.class, taskTableModel.new CommonCheckBoxEditor());
+ table.setDefaultEditor(JButton.class, taskTableModel.new CommonUploadEditor());
+ table.setDefaultEditor(JTextField.class, taskTableModel.new CommonTextFieldEditor());
+ table.setDefaultEditor(JComboBox.class, taskTableModel.new CommonComboBoxEditor());
+
+ table.setRowHeight(30);
+ table.setRowMargin(5);
+ JTableHeader jTableHeader = table.getTableHeader();
+
+ table.getColumnModel().getColumn(0).setMaxWidth(50);
+ table.getColumnModel().getColumn(4).setMaxWidth(150);
+ table.getColumnModel().getColumn(7).setMaxWidth(150);
+
+ getTaskPane().add(jTableHeader, BorderLayout.NORTH);
+ getTaskPane().add(table, BorderLayout.CENTER);
+
+ listener = new PDFSplitterListener(taskPane, taskTableModel);
+ listener.setNewTask(getNewTask());
+ listener.setStartTask(getStartTask());
+ listener.setHelpBtn(getHelpBtn());
+ listener.setComponents(taskTableModel.getComps());
+ listener.startListener();
+
+ getHelpBtn().setIcon(new FlatSVGIcon("icon/help.svg"));
+ }
+
+ /**
+ * Method generated by IntelliJ IDEA GUI Designer
+ * >>> IMPORTANT!! <<<
+ * DO NOT edit this method OR call it in your code!
+ *
+ * @noinspection ALL
+ */
+ private void $$$setupUI$$$() {
+ pdfPanel = new JPanel();
+ pdfPanel.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1));
+ final JTabbedPane tabbedPane1 = new JTabbedPane();
+ tabbedPane1.setTabPlacement(2);
+ pdfPanel.add(tabbedPane1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, new Dimension(200, 200), null, 0, false));
+ splitPane = new JPanel();
+ splitPane.setLayout(new GridLayoutManager(2, 4, new Insets(15, 15, 15, 15), -1, -1));
+ tabbedPane1.addTab("PDF拆分", splitPane);
+ startTask = new JButton();
+ startTask.setText("开始拆分");
+ splitPane.add(startTask, new GridConstraints(0, 3, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+ final Spacer spacer1 = new Spacer();
+ splitPane.add(spacer1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false));
+ taskPane = new JPanel();
+ taskPane.setLayout(new BorderLayout(0, 0));
+ splitPane.add(taskPane, new GridConstraints(1, 0, 1, 4, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
+ taskPane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(new Color(-2500135)), null, TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, null));
+ newTask = new JButton();
+ newTask.setText("新增处理任务");
+ splitPane.add(newTask, new GridConstraints(0, 2, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(50, 30), null, 0, false));
+ helpBtn = new JLabel();
+ helpBtn.setText("");
+ splitPane.add(helpBtn, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+ mergePane = new JPanel();
+ mergePane.setLayout(new GridLayoutManager(2, 4, new Insets(15, 15, 15, 15), -1, -1));
+ tabbedPane1.addTab("PDF合并", mergePane);
+ final Spacer spacer2 = new Spacer();
+ mergePane.add(spacer2, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false));
+ startMerge = new JButton();
+ startMerge.setText("开始合并");
+ mergePane.add(startMerge, new GridConstraints(0, 3, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+ addFile = new JButton();
+ addFile.setText("新增合并文件");
+ mergePane.add(addFile, new GridConstraints(0, 2, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+ helpMerge = new JLabel();
+ helpMerge.setText("");
+ mergePane.add(helpMerge, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
+ filePane = new JPanel();
+ filePane.setLayout(new BorderLayout(0, 0));
+ mergePane.add(filePane, new GridConstraints(1, 0, 1, 4, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
+ filePane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(new Color(-2500135)), null, TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, null));
+ }
+
+ /**
+ * @noinspection ALL
+ */
+ public JComponent $$$getRootComponent$$$() {
+ return pdfPanel;
+ }
+
+ public abstract class PDFTableModel extends AbstractTableModel {
+
+ protected String[] COLUMN_NAMES = new String[]{};
+
+ protected Class>[] COLUMN_TYPES = new Class>[]{};
+
+ protected List
");
+ tipsBuilder.append("5. 合并后的文件在桌面目录下,文件名为“merge.pdf”。
");
+ tipsBuilder.append("
6. 本功能仅支持未加密的PDF。
");
+
+ dialog.setHtmlText(tipsBuilder.toString());
+ dialog.pack();
+ dialog.setVisible(true);
+
+ super.mousePressed(e);
+ }
+
+ @Override
+ public void mouseEntered(MouseEvent e) {
+ JLabel label = (JLabel) e.getComponent();
+ label.setCursor(new Cursor(Cursor.HAND_CURSOR));
+ label.setIcon(UiConsts.HELP_FOCUSED_ICON);
+ super.mouseEntered(e);
+ }
+
+ @Override
+ public void mouseExited(MouseEvent e) {
+ JLabel label = (JLabel) e.getComponent();
+ label.setIcon(UiConsts.HELP_ICON);
+ super.mouseExited(e);
+ }
+ });
+ }
+
+ public void selectFile(File file, int row) {
+ String fileName = file.getName().toLowerCase();
+ if (!fileName.endsWith(".pdf")) {
+ showErrorMessage("错误:文件类型错误,该功能仅支持PDF格式文件。");
+ } else {
+ getPdfReader(file, reader -> {
+ JLabel label = get(row, 2, JLabel.class);
+ label.setText(file.getName());
+
+ int pages = reader.getNumberOfPages();
+ JTextField jTextField = get(row, 3, JTextField.class);
+ jTextField.setText("1-" + pages);
+
+ JProgressBar progressBar = get(row, 4, JProgressBar.class);
+ JLabel statusLabel = get(row, 5, JLabel.class);
+ progressBar.setValue(0);
+ progressBar.updateUI();
+ statusLabel.setText("未开始");
+
+ PdfParam param = getPdfParam(row);
+ param.setFile(file);
+ param.setPageRange("1-" + pages);
+ param.setMaxPage(pages);
+ });
+ model.fireTableRowsUpdated(row, row);
+ }
+ }
+
+ public void setStartMerge(JButton startMerge) {
+ this.startMerge = startMerge;
+ }
+
+ public void setHelpMerge(JLabel helpMerge) {
+ this.helpMerge = helpMerge;
+ }
+
+ public void setAddFile(JButton addFile) {
+ this.addFile = addFile;
+ }
+
+ private void startMerge() {
+ Document document= null;
+ PdfCopy pdfCopy = null;
+ int i = 0;
+ try {
+ checker();
+ document = new Document();
+ pdfCopy = new PdfCopy(document, new FileOutputStream(getOutputDir() + File.separator + "merge.pdf"));
+ document.open();
+ for (; i < this.components.size(); i++) {
+ PdfParam pdfParam = getPdfParam(i);
+ if (pdfParam.isMerge) {
+ copyPdf(pdfParam, document, pdfCopy);
+
+ JProgressBar progressBar = get(i, 4, JProgressBar.class);
+ progressBar.setValue(100);
+ JLabel label = get(i, 5, JLabel.class);
+ label.setText("已完成");
+ model.fireTableRowsUpdated(i, i);
+ }
+ }
+ } catch (IllegalArgumentException e) {
+ showErrorMessage("错误:" + e.getMessage());
+ JTextField jTextField = get(i, 3, JTextField.class);
+ PdfParam pdfParam = getPdfParam(i);
+ ThreadUtil.execute(() -> jTextField.setText("1-" + pdfParam.getMaxPage()));
+ } catch (Exception e) {
+ log.error("合并文件错误!", e);
+ } finally {
+ if (null != document) {
+ document.close();
+ }
+ if (null != pdfCopy) {
+ pdfCopy.close();
+ }
+ }
+ }
+
+ private T get(int row, int column, Class tClass) {
+ Object o = this.components.get(row)[column];
+ return tClass.cast(o);
+ }
+
+ private String getOutputDir() {
+ if (StringUtils.isBlank(this.outputDir)) {
+ synchronized (this) {
+ if (StringUtils.isBlank(this.outputDir)) {
+ this.outputDir = System.getProperty("user.home") + File.separator + "Desktop";
+ }
+ }
+ }
+ return this.outputDir;
+ }
+
+ private PdfParam getPdfParam(int row) {
+ PdfParam param = get(row, 6, PdfParam.class);
+ if (null == param) {
+ param = initParam();
+ this.components.get(row)[6] = param;
+ }
+ return param;
+ }
+
+ private PdfParam initParam() {
+ PdfParam param = new PdfParam();
+ param.setFile(null);
+ param.setPageRange(null);
+ param.setMaxPage(0);
+ return param;
+ }
+
+ private void showMessageDialog(String message, String title, int type) {
+ JOptionPane.showMessageDialog(jPanel, message, title, type);
+ }
+
+ private void showErrorMessage(String message) {
+ showMessageDialog(message, "错误", JOptionPane.ERROR_MESSAGE);
+ }
+
+ private void getPdfReader(File file, Consumer consumer) {
+ PdfReader reader = null;
+ try {
+ reader = new PdfReader(file.getAbsolutePath());
+ consumer.accept(reader);
+ } catch (Exception e) {
+ log.error("获取PDFReader出错!", e);
+ } finally {
+ if (null != reader) {
+ reader.close();
+ }
+ }
+ }
+
+ public void changeMergeRange(String text, int row) {
+ PdfParam pdfParam = getPdfParam(row);
+ pdfParam.setPageRange(text);
+ }
+
+ private void checker() throws IllegalArgumentException {
+ int mergeCount = 0;
+ for (int i = 0; i < this.components.size(); i++) {
+ PdfParam pdfParam = getPdfParam(i);
+ if (pdfParam.isMerge) {
+ if (null == pdfParam.getFile()) {
+ throw new IllegalArgumentException(String.format("第%d个没有选择PDF文件!", i + 1));
+ }
+ if (!rangeCompile.matcher(pdfParam.getPageRange()).find()) {
+ throw new IllegalArgumentException("PDF合并范围格式输入错误!");
+ }
+ validRange(pdfParam.getPageRange());
+ if (pdfParam.outOfRange()) {
+ throw new IllegalArgumentException(String.format("第%d个PDF文件合并范围有误,该PDF最大页数是%d!", i + 1, pdfParam.getMaxPage()));
+ }
+ mergeCount++;
+ }
+ }
+
+ if (mergeCount < 2) {
+ throw new IllegalArgumentException("待合并的PDF最少是2个!");
+ }
+ }
+
+ public void setMerge(boolean isSelected, int row) {
+ PdfParam pdfParam = getPdfParam(row);
+ pdfParam.setMerge(isSelected);
+ }
+
+ public void copyPdf(PdfParam param, Document document, PdfCopy pdfCopy) throws Exception {
+ getPdfReader(param.getFile(), reader -> {
+ int pages = reader.getNumberOfPages();
+ if (0 == pages) {
+ return;
+ }
+ Predicate predicate = num -> {
+ String[] ranges = param.pageRange.split(";");
+ for (String range : ranges) {
+ if (range.contains("-")) {
+ String[] split = range.split("-");
+ if (Integer.valueOf(split[0]) <= num && num <= Integer.valueOf(split[1])) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ for (int i = 1; i <= pages; i++) {
+ if (predicate.test(i)) {
+ document.newPage();
+ try {
+ pdfCopy.addPage(pdfCopy.getImportedPage(reader, i));
+ } catch (Exception e) {
+ log.error("PDF拷贝出错!", e);
+ }
+ }
+ }
+ });
+ }
+
+ private void validRange(String pageRange) {
+ String[] ranges = pageRange.split(";");
+ for (String range : ranges) {
+ if (range.contains("-")) {
+ String[] split = range.split("-");
+ if (Integer.valueOf(split[0]) > Integer.valueOf(split[1])) {
+ throw new IllegalArgumentException("PDF合并范围格式输入错误!");
+ }
+ }
+ }
+ }
+
+ public static class PdfParam {
+ /**
+ * 待合并PDF页面范围
+ */
+ private String pageRange;
+
+ private int maxPage;
+
+ private File file;
+
+ private boolean isMerge;
+
+ public String getPageRange() {
+ return pageRange;
+ }
+
+ public void setPageRange(String pageRange) {
+ this.pageRange = pageRange;
+ }
+
+ public int getMaxPage() {
+ return maxPage;
+ }
+
+ public void setMaxPage(int maxPage) {
+ this.maxPage = maxPage;
+ }
+
+ public File getFile() {
+ return file;
+ }
+
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ public boolean isMerge() {
+ return isMerge;
+ }
+
+ public void setMerge(boolean merge) {
+ isMerge = merge;
+ }
+
+ private boolean outOfRange() {
+ String[] ranges = this.pageRange.split(";");
+ for (String range : ranges) {
+ if (range.contains("-")) {
+ String[] split = range.split("-");
+ for (int i = Integer.valueOf(split[0]); i <= Integer.valueOf(split[1]); i++) {
+ if (i < 1 || maxPage < i) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+ }
+}
diff --git a/src/main/java/com/luoboduner/moo/tool/ui/listener/func/PDFSplitterListener.java b/src/main/java/com/luoboduner/moo/tool/ui/listener/func/PDFSplitterListener.java
new file mode 100755
index 00000000..03f074be
--- /dev/null
+++ b/src/main/java/com/luoboduner/moo/tool/ui/listener/func/PDFSplitterListener.java
@@ -0,0 +1,495 @@
+package com.luoboduner.moo.tool.ui.listener.func;
+
+import cn.hutool.core.thread.ThreadUtil;
+import com.itextpdf.text.Document;
+import com.itextpdf.text.pdf.PdfCopy;
+import com.itextpdf.text.pdf.PdfImportedPage;
+import com.itextpdf.text.pdf.PdfReader;
+import com.luoboduner.moo.tool.ui.UiConsts;
+import com.luoboduner.moo.tool.ui.dialog.CommonTipsDialog;
+import com.luoboduner.moo.tool.ui.form.func.PdfForm;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.math.NumberUtils;
+
+import javax.swing.*;
+import javax.swing.table.AbstractTableModel;
+import java.awt.*;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.regex.Pattern;
+import java.util.stream.Stream;
+
+@Slf4j
+public class PDFSplitterListener {
+
+ private JPanel jPanel;
+ private AbstractTableModel model;
+ private List components;
+
+ private JButton newTask;
+ private JLabel helpBtn;
+ private JButton startTask;
+
+ private static Pattern compile = Pattern.compile("^[0-9]+-[0-9]+$");
+ private static Pattern ruleCompile = Pattern.compile("^\\d+([-;]\\d+?)*?$");
+
+ public PDFSplitterListener(JPanel jPanel, AbstractTableModel model) {
+ this.jPanel = jPanel;
+ this.model = model;
+ }
+
+ public void selectFile(File file, int row) {
+ String fileName = file.getName().toLowerCase();
+ if (!fileName.endsWith(".pdf")) {
+ showErrorMessage("错误:文件类型错误,该功能仅支持PDF格式文件。");
+ } else {
+ JLabel label = get(row, 2, JLabel.class);
+ label.setText(file.getName());
+ getPdfReader(file, reader -> {
+ int pages = reader.getNumberOfPages();
+ JTextField jTextField = get(row, 3, JTextField.class);
+ jTextField.setText("1-" + pages);
+
+ JProgressBar progressBar = get(row, 6, JProgressBar.class);
+ JLabel statusLabel = get(row, 7, JLabel.class);
+ progressBar.setValue(0);
+ progressBar.updateUI();
+ statusLabel.setText("未开始");
+
+ PdfParam param = getPdfParam(row);
+ param.setFile(file);
+ param.setPageRange("1-" + pages);
+ param.setRule("");
+ param.setMaxPage(pages);
+ param.setSplitType(SplitType.ODD);
+ });
+ model.fireTableDataChanged();
+ }
+ }
+
+ private PdfParam initParam() {
+ PdfParam param = new PdfParam();
+ param.setFile(null);
+ param.setPageRange(null);
+ param.setRule("");
+ param.setMaxPage(0);
+ param.setSplitType(SplitType.ODD);
+ return param;
+ }
+
+ private PdfParam getPdfParam(int row) {
+ PdfParam param = get(row, 8, PdfParam.class);
+ if (null == param) {
+ param = initParam();
+ this.components.get(row)[8] = param;
+ }
+ return param;
+ }
+
+ public void changeSplitRange(String range, int row) {
+ PdfParam param = this.getPdfParam(row);
+ JTextField jTextField = get(row, 3, JTextField.class);
+ if (null == param.getFile()) {
+ return;
+ }
+
+ if (StringUtils.isBlank(range)) {
+ showErrorMessage("错误:拆分范围不能为空!");
+ return;
+ }
+
+ if (!compile.matcher(range).find()) {
+ showErrorMessage("错误:拆分范围内容输入错误,例如(1-20或15-15)!");
+ asyncRun(() -> jTextField.setText("1-" + param.getMaxPage()));
+ } else {
+ String[] split = range.split("-");
+ Integer start = NumberUtils.createInteger(split[0]);
+ Integer end = NumberUtils.createInteger(split[1]);
+ if (start > end) {
+ showErrorMessage("错误:拆分范围内容输入错误,例如(1-20或15-15)!");
+ asyncRun(() -> jTextField.setText("1-" + param.getMaxPage()));
+ return;
+ }
+ if (start < 1 || param.getMaxPage() < start) {
+ showErrorMessage("错误:拆分范围内容输入错误,拆分起始页只能是1-" + param.getMaxPage() + "中任一一个数字。");
+ asyncRun(() -> jTextField.setText("1-" + param.getMaxPage()));
+ return;
+ } else if (param.maxPage < end) {
+ showErrorMessage("错误:拆分范围内容输入错误,拆分终止页只能是1-" + param.getMaxPage() + "中任一一个数字。");
+ asyncRun(() -> jTextField.setText("1-" + param.getMaxPage()));
+ return;
+ }
+ param.setPageRange(range);
+ model.fireTableDataChanged();
+ }
+ }
+
+ public void changeSplitRuleType(String type, int row) {
+ SplitType splitType = SplitType.valueOfDesc(type);
+ PdfParam param = this.getPdfParam(row);
+ param.setSplitType(splitType);
+ JTextField customRule = this.get(row, 5, JTextField.class);
+ if (SplitType.CUSTOM == splitType) {
+ customRule.setEnabled(true);
+ } else {
+ customRule.setEnabled(false);
+ customRule.setText(null);
+ }
+ }
+
+ public void changeSplitRule(String rule, int row) {
+ if (StringUtils.isBlank(rule)) {
+ showErrorMessage("错误:自定义规则不能为空!");
+ return;
+ }
+ PdfParam param = this.getPdfParam(row);
+ param.setRule(rule);
+ }
+
+ public void setSplit(int row, boolean split) {
+ PdfParam param = this.getPdfParam(row);
+ param.setSplit(split);
+ }
+
+ private T get(int row, int column, Class tClass) {
+ Object o = this.components.get(row)[column];
+ return tClass.cast(o);
+ }
+
+ private void getPdfReader(File file, Consumer consumer) {
+ PdfReader reader = null;
+ try {
+ reader = new PdfReader(file.getAbsolutePath());
+ consumer.accept(reader);
+ } catch (Exception e) {
+ log.error("获取PDFReader出错!", e);
+ } finally {
+ if (null != reader) {
+ reader.close();
+ }
+ }
+ }
+
+ private String ruleChecker(String rule) {
+ if (StringUtils.isBlank(rule)) {
+ return "自定义规则不能为空!";
+ }
+ if (!ruleCompile.matcher(rule).find()) {
+ return "自定义规则格式输入错误!";
+ }
+ return null;
+ }
+
+ public void startSplit() {
+ List errs = new ArrayList<>(1);
+ forEachComponents((param, i) -> {
+ if (SplitType.CUSTOM == param.getSplitType()) {
+ String errorMsg = ruleChecker(param.getRule());
+ if (StringUtils.isNotBlank(errorMsg)) {
+ errs.add(0, "错误:" + param.getFile().getName() + errorMsg);
+ }
+ }
+ if (param.isSplit && null == param.getFile()) {
+ errs.add(0, String.format("错误:第%d个任务未选择文件!" , i + 1));
+ }
+ });
+
+ if (!errs.isEmpty()) {
+ showErrorMessage(errs.get(0));
+ return;
+ }
+
+ forEachComponents((param, i) -> {
+ JProgressBar progressBar = get(i, 6, JProgressBar.class);
+ progressBar.setValue(0);
+ model.fireTableCellUpdated(i, 6);
+ JLabel label = get(i, 7, JLabel.class);
+ label.setText("未开始");
+ model.fireTableCellUpdated(i, 7);
+ });
+
+ forEachComponents((param, n) -> {
+ PdfReader reader = null;
+ Document document = null;
+ PdfCopy pdfCopy = null;
+ try {
+ JProgressBar progressBar = get(n, 6, JProgressBar.class);
+ JLabel label = get(n, 7, JLabel.class);
+ label.setText("拆分中");
+ String filePath = param.getFile().getAbsolutePath();
+ String parent = param.getFile().getParent();
+ document = new Document();
+ pdfCopy = new PdfCopy(document, new FileOutputStream(parent + File.separator + newFileName(param.getFile().getName())));
+ reader = new PdfReader(filePath);
+ int numberOfPages = reader.getNumberOfPages();
+ document.open();
+ String pageRange = param.getPageRange();
+ String[] split = pageRange.split("-");
+ for (int i = 1; i <= numberOfPages; i++) {
+ if (Integer.valueOf(split[0]) <= i && i <= Integer.valueOf(split[1])) {
+ if (param.getSplitType().canSplit(i, param.getRule())) {
+ document.newPage();
+ PdfImportedPage page = pdfCopy.getImportedPage(reader, i);
+ pdfCopy.addPage(page);
+ }
+ }
+ progressBar.setValue((int)((float) i / (float) numberOfPages * 100));
+ progressBar.updateUI();
+ model.fireTableDataChanged();
+ }
+ label.setText("已完成");
+ model.fireTableDataChanged();
+ } catch (Exception e) {
+ log.error("拆分文件出错!", e);
+ } finally {
+ if (null != document) {
+ document.close();
+ }
+ if (null != pdfCopy) {
+ pdfCopy.close();
+ }
+ if (null != reader) {
+ reader.close();
+ }
+ }
+ });
+ }
+
+ private void asyncRun(Runnable runnable) {
+ ThreadUtil.execute(runnable);
+ }
+
+ private String newFileName(String fileName) {
+ String lowerCaseName = fileName.toLowerCase();
+ lowerCaseName = lowerCaseName.replace(".pdf", "");
+ return lowerCaseName + "_split.pdf";
+ }
+
+ private void forEachComponents(BiConsumer consumer) {
+ for (int i = 0; i < this.components.size(); i++) {
+ Object[] objects = this.components.get(i);
+ Object obj = objects[8];
+ if (null == obj) {
+ continue;
+ }
+ PdfParam param = (PdfParam) obj;
+ if (param.isSplit) {
+ consumer.accept(param, i);
+ }
+ }
+ }
+
+ public void startListener() {
+ startTask.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ super.mouseClicked(e);
+ startSplit();
+ }
+ });
+
+ newTask.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ super.mouseClicked(e);
+ ((PdfForm.PDFTableModel) model).add();
+ }
+ });
+
+ helpBtn.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mousePressed(MouseEvent e) {
+ CommonTipsDialog dialog = new CommonTipsDialog();
+
+ StringBuilder tipsBuilder = new StringBuilder();
+ tipsBuilder.append("关于PDF拆分
");
+ tipsBuilder.append("1. 该拆分功能默认可并行同时拆分10个PDF,可增加最大任务上线为20个。
");
+ tipsBuilder.append("2. 当勾选了待拆分的任务后,该任务才会生效。
");
+ tipsBuilder.append("3. PDF拆分范围默认1-最大页(PDF最大页),不可设置1-最大页以外的页数。
");
+ tipsBuilder.append("4. 拆分规则为“奇数”、“偶数”、“自定义”三种规则,都依托于前面的拆分范围,当设定拆分范围后,拆分器按照“奇数”、“偶数”、“自定义”进行拆分。
");
+ tipsBuilder.append("5. 拆分规则为“自定义”规则时,需要设定自定义规则,该规则可设置“范围”、“指定页”。
");
+ tipsBuilder.append("
");
+ tipsBuilder.append("- 范围:1-5;6-7
");
+ tipsBuilder.append("- 指定页:1;5;9;10
");
+ tipsBuilder.append("- 范围与指定页(指定页与指定页,范围与范围)之间,需要用英文分号“;”隔开
");
+ tipsBuilder.append("
");
+ tipsBuilder.append("6. 拆分后的文件在源文件的同级目录下,后缀为“_split.pdf”。
");
+ tipsBuilder.append("
7. 本功能仅支持未加密的PDF。
");
+
+ dialog.setHtmlText(tipsBuilder.toString());
+ dialog.pack();
+ dialog.setVisible(true);
+
+ super.mousePressed(e);
+ }
+
+ @Override
+ public void mouseEntered(MouseEvent e) {
+ JLabel label = (JLabel) e.getComponent();
+ label.setCursor(new Cursor(Cursor.HAND_CURSOR));
+ label.setIcon(UiConsts.HELP_FOCUSED_ICON);
+ super.mouseEntered(e);
+ }
+
+ @Override
+ public void mouseExited(MouseEvent e) {
+ JLabel label = (JLabel) e.getComponent();
+ label.setIcon(UiConsts.HELP_ICON);
+ super.mouseExited(e);
+ }
+ });
+ }
+
+ private void showMessageDialog(String message, String title, int type) {
+ JOptionPane.showMessageDialog(jPanel, message, title, type);
+ }
+
+ private void showErrorMessage(String message) {
+ showMessageDialog(message, "错误", JOptionPane.ERROR_MESSAGE);
+ }
+
+ public static class PdfParam {
+ /** 待拆分PDF页面范围 */
+ private String pageRange;
+ /** 拆分类型 */
+ private SplitType splitType;
+ /** 拆分规则 */
+ private String rule;
+
+ private int maxPage;
+
+ private File file;
+
+ private boolean isSplit;
+
+ public String getPageRange() {
+ return pageRange;
+ }
+
+ public void setPageRange(String pageRange) {
+ this.pageRange = pageRange;
+ }
+
+ public SplitType getSplitType() {
+ return splitType;
+ }
+
+ public void setSplitType(SplitType splitType) {
+ this.splitType = splitType;
+ }
+
+ public String getRule() {
+ return rule;
+ }
+
+ public void setRule(String rule) {
+ this.rule = rule;
+ }
+
+ public File getFile() {
+ return file;
+ }
+
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ public int getMaxPage() {
+ return maxPage;
+ }
+
+ public void setMaxPage(int maxPage) {
+ this.maxPage = maxPage;
+ }
+
+ public boolean isSplit() {
+ return isSplit;
+ }
+
+ public void setSplit(boolean split) {
+ isSplit = split;
+ }
+ }
+
+ public interface SplitRule {
+ boolean canSplit(Integer num, String rule);
+ }
+
+ public enum SplitType implements SplitRule {
+ EVEN("偶数") {
+ @Override
+ public boolean canSplit(Integer num, String rule) {
+ return num % 2 == 0;
+ }
+ },
+ ODD("奇数") {
+ @Override
+ public boolean canSplit(Integer num, String rule) {
+ return num % 2 != 0;
+ }
+ },
+ CUSTOM("自定义") {
+ @Override
+ public boolean canSplit(Integer num, String rule) {
+ String[] args = rule.split(";");
+ for (String elem : args) {
+ if (elem.contains("-")) {
+ String[] split = elem.split("-");
+ if (Integer.valueOf(split[0]) <= num && num <= Integer.valueOf(split[1])) {
+ return true;
+ }
+ } else {
+ if (Integer.valueOf(elem).compareTo(num) == 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ };
+
+ private String desc;
+
+ SplitType(String desc) {
+ this.desc = desc;
+ }
+
+ public static SplitType valueOfDesc(String desc) {
+ return Stream.of(SplitType.values())
+ .filter(item -> item.getDesc().equals(desc))
+ .findAny()
+ .orElse(null);
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+
+ public void setDesc(String desc) {
+ this.desc = desc;
+ }
+ }
+
+ public void setComponents(List components) {
+ this.components = components;
+ }
+
+ public void setNewTask(JButton newTask) {
+ this.newTask = newTask;
+ }
+
+ public void setHelpBtn(JLabel helpBtn) {
+ this.helpBtn = helpBtn;
+ }
+
+ public void setStartTask(JButton startTask) {
+ this.startTask = startTask;
+ }
+}
diff --git a/src/main/java/com/luoboduner/moo/tool/util/FileReformatUtil.java b/src/main/java/com/luoboduner/moo/tool/util/FileReformatUtil.java
new file mode 100755
index 00000000..e57b3e54
--- /dev/null
+++ b/src/main/java/com/luoboduner/moo/tool/util/FileReformatUtil.java
@@ -0,0 +1,88 @@
+package com.luoboduner.moo.tool.util;
+
+import de.hunsicker.jalopy.Jalopy;
+import de.hunsicker.jalopy.storage.Convention;
+import de.hunsicker.jalopy.storage.ConventionKeys;
+import org.jsoup.Jsoup;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.File;
+import java.io.StringWriter;
+
+public class FileReformatUtil {
+
+ private static DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ private static TransformerFactory transformerFactory = TransformerFactory.newInstance();
+ private static Jalopy jalopy = new Jalopy();
+
+ public static String reformatXML(File file, int spaceNum) throws Exception {
+ StringWriter res = new StringWriter();
+ try {
+ // 创建DocumentBuilder对象
+ DocumentBuilder builder = factory.newDocumentBuilder();
+
+ // 解析XML文件并返回Document对象
+ Document document = builder.parse(file);
+ // 获取文档的根元素
+ Element rootElement = document.getDocumentElement();
+
+ // 设置格式化属性,这里使用缩进和换行
+ document.setXmlStandalone(true);
+ document.setXmlVersion("1.0");
+ rootElement.normalize();
+
+ // 创建Transformer对象
+ Transformer transformer = transformerFactory.newTransformer();
+
+ // 设置输出格式化属性,这里使用缩进和换行
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8");
+ transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", String.valueOf(spaceNum));
+
+ // 创建DOMSource对象
+ DOMSource source = new DOMSource(document);
+
+ // 创建StreamResult对象,指定输出位置
+ StreamResult result = new StreamResult(res);
+
+ // 格式化XML并输出结果
+ transformer.transform(source, result);
+
+ return res.toString();
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ res.close();
+ }
+ }
+
+ public static String reformatHTML(File file, int spaceNum) throws Exception {
+ return Jsoup.parse(file, "UTF-8")
+ .outputSettings(new org.jsoup.nodes.Document.OutputSettings().indentAmount(spaceNum))
+ .outerHtml();
+ }
+
+ public static String reformatJAVA(File file, int spaceNum) throws Exception {
+ Convention instance = Convention.getInstance();
+ instance.put(ConventionKeys.SPACE_BEFORE_BRACES, "true");
+ instance.put(ConventionKeys.SPACE_BEFORE_BRACKETS, "true");
+ instance.put(ConventionKeys.INDENT_SIZE, String.valueOf(spaceNum));
+
+ try (StringWriter stringWriter = new StringWriter()) {
+ jalopy.setInput(file);
+ jalopy.setOutput(stringWriter);
+ jalopy.format();
+ return stringWriter.toString();
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+}
diff --git a/src/main/java/com/luoboduner/moo/tool/util/XmlReformatUtil.java b/src/main/java/com/luoboduner/moo/tool/util/XmlReformatUtil.java
new file mode 100755
index 00000000..479c353f
--- /dev/null
+++ b/src/main/java/com/luoboduner/moo/tool/util/XmlReformatUtil.java
@@ -0,0 +1,61 @@
+package com.luoboduner.moo.tool.util;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.File;
+import java.io.StringWriter;
+
+public class XmlReformatUtil {
+
+ private static DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ private static TransformerFactory transformerFactory = TransformerFactory.newInstance();
+
+ public static String reformat(File file, int spaceNum) throws Exception {
+ StringWriter res = new StringWriter();
+ try {
+ // 创建DocumentBuilder对象
+ DocumentBuilder builder = factory.newDocumentBuilder();
+
+ // 解析XML文件并返回Document对象
+ Document document = builder.parse(file);
+ // 获取文档的根元素
+ Element rootElement = document.getDocumentElement();
+
+ // 设置格式化属性,这里使用缩进和换行
+ document.setXmlStandalone(true);
+ document.setXmlVersion("1.0");
+ rootElement.normalize();
+
+ // 创建Transformer对象
+ Transformer transformer = transformerFactory.newTransformer();
+
+ // 设置输出格式化属性,这里使用缩进和换行
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8");
+ transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", String.valueOf(spaceNum));
+
+ // 创建DOMSource对象
+ DOMSource source = new DOMSource(document);
+
+ // 创建StreamResult对象,指定输出位置
+ StreamResult result = new StreamResult(res);
+
+ // 格式化XML并输出结果
+ transformer.transform(source, result);
+
+ return res.toString();
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ res.close();
+ }
+ }
+}
diff --git a/src/main/resources/icon/gear.svg b/src/main/resources/icon/gear.svg
new file mode 100755
index 00000000..be702269
--- /dev/null
+++ b/src/main/resources/icon/gear.svg
@@ -0,0 +1,28 @@
+
+
+
diff --git a/src/main/resources/icon/pdf.svg b/src/main/resources/icon/pdf.svg
new file mode 100755
index 00000000..25ae4eba
--- /dev/null
+++ b/src/main/resources/icon/pdf.svg
@@ -0,0 +1,13 @@
+
+
+