記一次糟糕的開發經歷[文本匹配器]--swing框架使用
一.前言
1.寫在前面
筆者最近因爲公司裏的一些~~開心事(糟心事還差不多)~~裸辭在家,一方面想換個工作環境。換換心情.另一方面也想找段時間好好沉澱一下自己。因此步入了失業人羣,沒事的時候在家看看書擼擼代碼過得也還行。今天在整理自己工作筆記的時候發現找代碼段真的好麻煩,每次都要打開文件一點一點看,因此就萌生了一個想法就是自己寫一個文本匹配器。
爲什麼說是糟糕的開發經歷呢?一方面是因爲工作,當然這不是重要的事情。最重要的是因爲長時間從事web開發Swing框架幾乎已經忘完了,所以才造就了這次磕磕絆絆的糟糕開發經歷。
2.實現目標及效果圖
A.實現目標
實現目標: 給定一段文本,選擇若干個文件,點擊搜索顯示文件信息和搜索結果。
B.效果圖
由於是筆者爲了方便自己偷懶而開發的軟件,所以界面並不好看,剛好我對這些地方也並不怎麼在意,所以就湊合着用吧。界面效果圖如1.2.1所示,運行效果圖如1.2.2和1.2.3所示。
看完了這些吐槽的話,下面開始我們的開發之旅。當然在開發之前首先要了解一些知識點。這次的開發主要涉及以下知識:
知識點 | 作用 |
---|---|
Swing框架 | 用於搭建項目界面 |
POI | 用來操作Word、Excel等文檔當然這裏只涉及讀取 |
File類 | 用於操作文件 |
IO流 | 用來對文檔內容進行讀寫,比如BufferWriter、BufferReader等 |
二.Swing框架和POI介紹
1.Swing框架介紹
1.什麼是Swing?
Swing是一個用於開發Java應用程序用戶界面的開發工具包。它以抽象窗口工具包(AWT)爲基礎使跨平臺應用程序可以使用任何可插拔的外觀風格。Swing開發人員只用很少的代碼就可以利用Swing豐富、靈活的功能和模塊化組件來創建優雅的用戶界面。
Swing 圍繞 JComponent 組件構建,JComponent 則由 AWT 的容器類擴展而來。Swing 組織結構如圖 2.1.1 所示。
2.Swing中的容器介紹
Swing 中容器可以分爲兩類:頂層容器和中間容器。
- 頂層容器
頂層容器是進行圖形編程的基礎,一切圖形化的東西都必須包括在頂層容器中。頂層容器是任何圖形界面程序都要涉及的主窗口,是顯示並承載組件的容器組件。
種類 | 介紹 |
---|---|
JFrame | 用於框架窗口的類,此窗口帶有邊框、標題、關閉和最小化窗口的圖標。帶 GUI 的應用程序至少使用一個框架窗口 |
JDialog | 用於對話框的類,主要用於彈出各種對話框 |
JApplet | 用於使用 Swing 組件的 Java Applet 類,主要用於在瀏覽器內顯示一個小程序界面 |
- 中間容器
中間容器是容器組件的一種,也可以承載其他組件,但中間容器不能獨立顯示,必須依附於其他的頂層容器。
種類 | 介紹 |
---|---|
JPanel | 表示一個普通面板,是最靈活、最常用的中間容器 |
JScrollPane | 與 JPanel 類似,但它可在大的組件或可擴展組件周圍提供滾動條 |
JTabbedPane | 表示選項卡面板,可以包含多個組件,但一次只顯示一個組件,用戶可在組件之間方便地切換 |
JToolBar | 表示工具欄,按行或列排列一組組件(通常是按鈕) |
3.一些容器與按鈕的寫法
在這個項目中用到的頂層容器:JFrame、JDialog,中間容器有JPanel、JScrollPane、JTabbedPane,下面簡單看下這幾個容器的用法:
// 創建頂層容器 JFrame
JFrame frame = new JFrame("文本匹配器");
// 設置窗口不可自由變換大小
frame.setResizable(false);
// 設置窗口大小
frame.setSize(600,500);
// 設置窗口相對於指定組件的位置--null表示窗口位於屏幕中央
frame.setLocationRelativeTo(null);
// 設置窗口左上角圖標(默認是Java的咖啡圖標)
ImageIcon imageIcon = new ImageIcon("src/main/java/matching.jpg");
frame.setIconImage(imageIcon.getImage());
// 窗口關閉按鈕
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
// 設置窗口、控件可見性
frame.setVisible(true);
//效果圖如圖2.1.2所示
// 創建對話框 JDialog
//初始化文件選擇框
JFileChooser fDialog = new JFileChooser();
//設置文件選擇框的標題
fDialog.setDialogTitle("請選擇文件");
//設置文件多選
fDialog.setMultiSelectionEnabled(true);
//彈出選擇框
int returnVal = fDialog.showOpenDialog(null);
//效果圖如圖2.1.3所示
// 創建普通面板 JPanel
//創建一個JFrame對象
JFrame jf=new JFrame("Java第二個GUI程序");
//設置窗口大小和位置
jf.setBounds(300, 100, 400, 200);
//創建一個JPanel對象
JPanel jp=new JPanel();
//創建一個標籤
JLabel jl=new JLabel("這是放在JPanel上的標籤");
//設置背景色
jp.setBackground(Color.white);
//將標籤添加到面板
jp.add(jl);
//將面板添加到窗口
jf.add(jp);
//設置窗口可見
jf.setVisible(true);
//效果圖如圖2.1.4所示
// 創建可滾動面板
// 創建文本域(圖中亮白色部分)
JTextArea target = new JTextArea(10,50);
// 初始化可滾動面板
JScrollPane scrollPane_top=new JScrollPane();
// 將文本域添加到可滾動面板中
scrollPane_top.setViewportView(target);
//效果圖如圖2.1.5所示(被黑色矩形選中的部分)
// 創建選項卡面板
// 創建文本域
JTextArea target = new JTextArea(10,50);
// 初始化選項卡面板
JTabbedPane tabbedPane_top = new JTabbedPane();
// 初始化可滾動面板
JScrollPane scrollPane_top=new JScrollPane();
// 將可滾動面板添加到選項卡面板中
tabbedPane_top.addTab("目標文本",null,scrollPane_top,null);
// 將文本域添加到可滾動面板中
scrollPane_top.setViewportView(target);
// 從這裏可以看出中間層容器可以承載其他組件(中間層容器也是組件,即容器組件)
//效果圖如圖2.1.6所示(被紅色矩形選中的部分)
- Swing中的控件介紹
常用的控件有按鈕,文本域,文本框,單選框,複選框等等。每個控件可以添加相應的監聽事件(對比HTML頁面)對以一些操作(如:點擊,得到焦點,失去焦點等)進行響應,這裏以按鈕(JButton)爲例介紹其創建及綁定事件。
// 創建一個右對齊佈局的普通面板
JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
// 創建一個叫“選擇文件”的按鈕
JButton chooseFile = new JButton("選擇文件");
// 爲按鈕添加事件監聽
chooseFile.addActionListener(new ActionListener() {
// 當按鈕被點擊是執行chooseFile()方法
@Override
public void actionPerformed(ActionEvent e) {
chooseFile(addressArea);
}
});
// 將按鈕添加到普通面板是
panel.add(chooseFile,BorderLayout.NORTH);
當然,這裏只是舉個栗子,並不代表按鈕只有點擊事件。其他的一些事件在項目中用到就會講解,如果沒用到並且你真的想知道的話,建議點擊xietansheng的博客(博主真的很走心)或者點擊C語言中文網來學習更多的Swing相關知識。
2.POI介紹
1.什麼是POI
POI全稱是Apache POI(點擊查看官方文檔)或Java POI。是Apache基金會的開源函式庫,POI提供API給Java程序對Microsoft Office格式檔案讀和寫的功能。
2.基本功能
- POIFS : 此組件是所有其他POI元件的基本因素。它被用來明確地讀取不同的文件。
- HSSF : 它被用來讀取和寫入MS-Excel的xls擴展名的文件。
- XSSF : 它是用於MS-Excel的xlsx擴展名的文件。
- HPSF : 它用來提取MS-Office文件屬性設置。
- HWPF : 它是用來讀取和寫入MS-Word的doc擴展名的文件。
- XWPF : 它是用來讀取和寫入MS-Word的docx擴展名的文件。
- HSLF : 它是用於讀取,創建和編輯PowerPoint演示文稿。
- HDGF : 它包含類和方法爲MS-Visio的二進制文件。
- HPBF : 它被用來讀取和寫入MS-Publisher文件。
3.基本用法(Word&Excel)
1.操作Excel文檔
這部分代碼摘抄自百度百科POI (Apache POI),代碼很簡單,跑一遍就能弄懂。
- 創建Excel文檔
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
import java.io.FileOutputStream;
public class CreateXL {
/** Excel 文件要存放的位置,假定在D盤下*/
public static String outputFile = "D:\\test.xls";
public static void main(String argv[]) {
try {
// 創建新的Excel 工作簿
HSSFWorkbook workbook = new HSSFWorkbook();
// 在Excel工作簿中建一工作表,其名爲缺省值
// 如要新建一名爲"效益指標"的工作表,其語句爲:
// HSSFSheet sheet = workbook.createSheet("效益指標");
HSSFSheet sheet = workbook.createSheet();
// 在索引0的位置創建行(最頂端的行)
HSSFRow row = sheet.createRow((short)0);
//在索引0的位置創建單元格(左上端)
HSSFCell cell = row.createCell((short)0);
// 定義單元格爲字符串類型
cell.setCellType(HSSFCell.CELL_TYPE_STRING);//已過時
// 在單元格中輸入一些內容
cell.setCellValue("增加值");
// 新建一輸出文件流
FileOutputStream fOut = new FileOutputStream(outputFile);
// 把相應的Excel 工作簿存盤
workbook.write(fOut);
fOut.flush();
// 操作結束,關閉文件
fOut.close();
System.out.println("文件生成...");
} catch (Exception e) {
System.out.println("已運行 xlCreate() : " + e);
}
}
}
- 讀取Excel文檔
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
import java.io.FileInputStream;
public class ReadXL {
/** Excel文件的存放位置。注意是反斜線*/
public static String fileToBeRead = "D:\\test1.xls";
public static void main(String argv[]) {
try {
// 創建對Excel工作簿文件的引用
HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(fileToBeRead));
// 創建對工作表的引用。
// 本例是按名引用(讓我們假定那張表有着缺省名"Sheet1")
HSSFSheet sheet = workbook.getSheet("Sheet1");
// 也可用getSheetAt(int index)按索引引用,
// 在Excel文檔中,第一張工作表的缺省索引是0,
// 其語句爲:HSSFSheet sheet = workbook.getSheetAt(0);
// 讀取左上端單元
HSSFRow row = sheet.getRow(0);
HSSFCell cell = row.getCell((short)0);
// 輸出單元內容,cell.getStringCellValue()就是取所在單元的值
System.out.println("左上端單元是: " + cell.getStringCellValue());
} catch (Exception e) {
System.out.println("已運行xlRead() : " + e);
}
}
}
2.操作Word文檔
- 創建Word文檔
// 創建Word文件
XWPFDocument doc = new XWPFDocument();
// 新建一個段落
XWPFParagraph p = doc.createParagraph();
// 設置段落的對齊方式
p.setAlignment(ParagraphAlignment.CENTER);
//設置下邊框
p.setBorderBottom(Borders.DOUBLE);
//設置上邊框
p.setBorderTop(Borders.DOUBLE);
//設置右邊框
p.setBorderRight(Borders.DOUBLE);
//設置左邊框
p.setBorderLeft(Borders.DOUBLE);
//創建段落文本
XWPFRun r = p.createRun();
r.setText("POI創建的Word段落文本");
//設置爲粗體
r.setBold(true);
//設置顏色
r.setColor("FF0000");
// 新建一個段落
p = doc.createParagraph();
r = p.createRun();
r.setText("POI讀寫Excel功能強大、操作簡單。");
//創建一個表格
XWPFTable table= doc.createTable(3, 3);
table.getRow(0).getCell(0).setText("表格1");
table.getRow(1).getCell(1).setText("表格2");
table.getRow(2).getCell(2).setText("表格3");
FileOutputStream out = newFileOutputStream("d:\\POI\\sample.doc");
doc.write(out);
out.close();
// 效果圖如圖2.2.1所示
- 讀取Word文檔
代碼很簡單,一看就懂,這裏就不放效果圖了
FileInputStream stream = newFileInputStream("d:\\POI\\sample.doc");
// 創建Word文件
XWPFDocument doc = new XWPFDocument(stream);
//遍歷段落
for(XWPFParagraph p : doc.getParagraphs()){
// 獲取每段的文字
System.out.print(p.getParagraphText());
}
//遍歷表格
for(XWPFTable table : doc.getTables()){
// 遍歷行
for(XWPFTableRow row : table.getRows()){
// 遍歷該行的單元格
for(XWPFTableCell cell : row.getTableCells()){
// 獲取單元格中的文字
System.out.print(cell.getText());
}
}
}
三.文本適配器開發
PS:💔💔💔深夜寫作不易,已經03:03:25了😭😭😭終於寫到第三部分了
首先創建一個maven項目(因爲要引入POI),在pom.xml中的<dependencies></dependencies>
標籤內添加如下代碼,引入POI
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.10-FINAL</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.10-FINAL</version>
</dependency>
1.畫窗口
- 創建Window類並繼承JFrame類,作爲程序頁面的繪製類
public class Window extends JFrame {
public Window(){
// 創建頂層容器
JFrame frame = new JFrame("文本匹配器");
frame.setResizable(false);
frame.setSize(600,500);
frame.setLocationRelativeTo(null);
// 設置左上角圖標
ImageIcon imageIcon = new ImageIcon("src/main/java/matching.jpg");
frame.setIconImage(imageIcon.getImage());
// 窗口關閉
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
- 創建ExecuteFrame類作爲繪製中間容器的類,定義setExecuteFrame()方法
public class ExecuteFrame {
JTextArea target = new JTextArea(10,50);
JTextField characterSet = new JTextField(6);
JTextArea addressArea = new JTextArea(13,50);
JTextArea textArea = new JTextArea(13,50);
public Box setExecuteFrame(){
JTabbedPane tabbedPane_top = new JTabbedPane();
JScrollPane scrollPane_top=new JScrollPane();
tabbedPane_top.addTab("目標文本",null,scrollPane_top,null);
// 爲target文本域添加焦點監聽(用於顯示或隱藏提示性文字)
target.addFocusListener(new TooltipTextForArea(target));
scrollPane_top.setViewportView(target);
JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
panel.add(new JLabel("字符集:"));
characterSet.setText("UTF-8");
panel.add(characterSet);
JButton chooseFile = new JButton("選擇文件");
// 添加選擇文件按鈕事件監聽
chooseFile.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
chooseFile(addressArea);
}
});
panel.add(chooseFile,BorderLayout.NORTH);
JButton clear = new JButton("清空");
// 添加清空按鈕事件監聽
clear.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
clearAction(target,addressArea,textArea);
}
});
panel.add(clear,BorderLayout.NORTH);
JButton search = new JButton("搜索");
// 添加搜索按鈕事件監聽
search.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
searchAction(target,addressArea,characterSet,textArea);
}
});
panel.add(search,BorderLayout.NORTH);
JTabbedPane tabbedPane = new JTabbedPane();
JScrollPane scrollPane1=new JScrollPane();
tabbedPane.addTab("文件列表",null,scrollPane1,null);
scrollPane1.setViewportView(addressArea);
JScrollPane scrollPane2=new JScrollPane();
tabbedPane.addTab("匹配結果",null,scrollPane2,null);
scrollPane2.setViewportView(textArea);
Box box = Box.createVerticalBox();
box.add(tabbedPane_top,BorderLayout.CENTER);
box.add(panel,BorderLayout.CENTER);
box.add(tabbedPane,BorderLayout.CENTER);
return box;
}
}
- 在Window類中調用setExecuteFrame()方法,將中間容器添加到頂層容器中
frame.setContentPane(new ExecuteFrame().setExecuteFrame());
2.寫監聽方法
- 在ExecuteFrame類中增加選擇文件按鈕監聽方法(chooseFile())
public void chooseFile(JTextArea field){
// System.out.println("----------"+field.getText());
StringBuffer buffer = new StringBuffer(field.getText());
//初始化文件選擇框
JFileChooser fDialog = new JFileChooser();
//設置文件選擇框的標題
fDialog.setDialogTitle("請選擇文件");
// 設置文件多選
fDialog.setMultiSelectionEnabled(true);
//彈出選擇框
int returnVal = fDialog.showOpenDialog(null);
// 如果是選擇了文件
if(JFileChooser.APPROVE_OPTION == returnVal){
//打印出文件的路徑,你可以修改位 把路徑值 寫到 textField 中
File[] files = fDialog.getSelectedFiles();
for (File file : files) {
String fileAddress = file.toString();
if ("".equals(field.getText())) {
buffer.append(fileAddress);
} else {
if (!(field.getText()).contains(fileAddress)) {
buffer.append(fileAddress);
}
}
buffer.append("\n");
}
}
// 將選擇的文件添加到field文本域中
field.setText(buffer.toString());
}
- 在ExecuteFrame類中增加清空按鈕監聽方法(clearAction())
private void clearAction(JTextArea target, JTextArea addressArea, JTextArea textArea) {
target.setText("");
addressArea.setText("");
textArea.setText("");
}
- 在ExecuteFrame類中增加搜索按鈕監聽方法(searchAction())
private void searchAction(JTextArea target, JTextArea address, JTextField characterSet, JTextArea textArea) {
StringBuffer resulet = new StringBuffer("");
String targetStr = target.getText();
System.out.println(targetStr);
String charSet = charSetHandler(characterSet.getText());
String filePath = address.getText();
String[] filePaths = filePath.split("\n");
for (String path : filePaths) {
resulet.append(fileHandler(path,targetStr,charSet));
}
textArea.setText(resulet.toString());
}
- 定義TooltipTextForArea類並實現FocusListener接口
- 聲明構造方法
- 定義字符串常量hintText作爲提示性文字內容,並提供Getter方法
- 重寫focusGained()(獲得焦點)和focusLost()(失去焦點)方法
public class TooltipTextForArea implements FocusListener {
private static String hintText = "1.目標文本框不能爲空;\n" +
"2.默認字符集爲UTF-8;\n" +
"3.文件選擇操作不支持回退功能,即選錯只能點擊清空按鈕進行重置;";
private JTextArea textArea;
public static String getHintText() {
return hintText;
}
public TooltipTextForArea(){}
public TooltipTextForArea(JTextArea textArea) {
this.textArea = textArea;
textArea.setText(TooltipTextForArea.hintText);
textArea.setForeground(Color.GRAY);
}
@Override
public void focusGained(FocusEvent e) {
//獲取焦點時,清空提示內容
String temp = textArea.getText();
if(temp.equals(TooltipTextForArea.hintText)) {
textArea.setText("");
textArea.setForeground(Color.BLACK);
}
}
@Override
public void focusLost(FocusEvent e) {
//失去焦點時,沒有輸入內容,顯示提示內容
String temp = textArea.getText();
if(temp.equals("")) {
textArea.setForeground(Color.GRAY);
textArea.setText(TooltipTextForArea.hintText);
}
}
}
- 在ExecuteFrame類中增加文件處理方法(fileHandler())
public String fileHandler(String filePath,String targetStr,String charSet){
StringBuffer result = new StringBuffer("");
boolean matchingState = false;
// 常見File對象
File file = new File(filePath);
if ("".equals(filePath)){
result.append("ERROR===========================================================================\n");
result.append("未選擇文件!\n");
result.append("END==============================================================================\n");
return result.toString();
}
result.append("文件信息:\n");
result.append("=================================================================================\n");
if (!file.exists()){
result.append("未在["+filePath.substring(0,filePath.lastIndexOf("\\"))+"]找到文件名爲["+filePath.substring(filePath.lastIndexOf("\\")+1)+"]的文件!\n");
result.append("文件不存在!\n");
result.append("匹配信息:\n");
result.append("=================================================================================\n");
result.append("無匹配結果.\n");
result.append("=================================================================================\n");
}else {
result.append("文件位置: "+filePath+".\n");
result.append("文件名稱: "+file.getName()+".\n");
result.append("最後修改時間: "+new Date(file.lastModified())+".\n");
result.append("文件大小: "+file.length()+"字節.\n");
result.append("是否隱藏:" + (file.isHidden() ? "是隱藏文件.\n" : "不是隱藏文件.\n"));
result.append("=================================================================================\n");
result.append("匹配信息:\n");
result.append("=================================================================================\n");
if (filePath.contains(".doc")||filePath.contains(".docx")){
result.append(new PoiRead().readWordForPoi(filePath,targetStr));
}else {
result.append(new PoiRead().readerOtherFile(filePath, targetStr, charSet));
}
result.append("=================================================================================\n\n");
}
return result.toString();
}
- 在ExecuteFrame類中增加字符集方法(charSetHandler())
public String charSetHandler(String arg){
String result = "";
switch (arg){
case "GBK":case "gbk":
result = "GBK";
break;
case "UTF-8": case "utf-8": case "utf8": default:
result="utf8";
}
return result;
}
3.處理文件
創建PoiRead類,將所有的文件讀寫操作交給這個類來完成。由於我這裏想獲得一個如圖3.3.1所示的匹配結果,所以要對Word中的數據進行行編號,所以應該聲明一個方法(fileHandler())來進行操作。
同時,考慮到Word文件與非Word文件的差異性,所以應該定義兩個方法來對應處理Word文件和非Word文件。
- 處理非Word文件的方法readerOtherFile()(.java、.txt等)
public String readerOtherFile(String fullFilePath,String targetStr,String charSet){
boolean matchingState = false;
StringBuffer buffer = new StringBuffer("");
File file = new File(fullFilePath);
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file),charSet));
String tempStr = null;
int line = 1;
if ((TooltipTextForArea.getHintText()).equals(targetStr)){
buffer.append("無匹配結果(空值匹配)!\n");
return buffer.toString();
}
while ((tempStr = reader.readLine()) != null){
System.out.println(line+" : "+tempStr);
if (tempStr.contains(targetStr)){
buffer.append("在第"+line+"行發現目標值! ["+tempStr+"]\n");
matchingState = true;
}
line++;
}
if (!matchingState){
buffer.append("無匹配結果.\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return buffer.toString();
}
- 處理Word文件的方法readWordForPoi()&readDocNew()(.doc、.docx等)
public String readWordForPoi(String fullFilePath,String targetStr){
StringBuilder builder = new StringBuilder("");
// 解析fullFilePath
String filePath = fullFilePath.substring(0,fullFilePath.lastIndexOf("\\")+1);
String fileName = fullFilePath.substring(fullFilePath.lastIndexOf("\\")+1);
System.out.println("filePath = " + filePath + ", fileName = " + fileName);
try {
builder.append(readDocNew(targetStr,filePath,fileName));
} catch (IOException e) {
e.printStackTrace();
} catch (OpenXML4JException e) {
e.printStackTrace();
} catch (XmlException e) {
e.printStackTrace();
}
return builder.toString();
}
public String readDocNew(String targetStr, String filePath, String fileName) throws IOException, OpenXML4JException, XmlException {
StringBuilder stringBuilder = new StringBuilder("");
XWPFWordExtractor extractor;
extractor = new XWPFWordExtractor(OPCPackage.open(new FileInputStream(filePath+fileName)));
String wordText = extractor.getText();
System.out.println(wordText);
stringBuilder.append(fileHandler(filePath,fileName,wordText,targetStr));
System.out.println(stringBuilder.toString());
return stringBuilder.toString();
}
- 處理Word文件數據的行編號的方法fileHandler()
public String fileHandler(String filePath, String fileName, String wordText, String targetStr) throws IOException {
StringBuffer buffer = new StringBuffer("");
// 創建臨時文件
File file = new File(filePath+"copy"+fileName.substring(0,fileName.lastIndexOf("."))+".txt");
BufferedWriter writer = null;
BufferedReader reader = null;
if (file.exists()){
file.delete();
file.createNewFile();
}
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"utf8"));
// 數據寫出
writer.write(wordText,0,wordText.length());
// 刷新緩衝區
writer.flush();
// 關閉writer流
writer.close();
// 數據寫入內存
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file),"utf8"));
buffer.append(readerFile(reader,targetStr));
// 關閉reader流
reader.close();
// 刪除臨時文件
file.delete();
return buffer.toString();
}
- 處理文件匹配問題並返回如圖3.3.1中的數據格式的方法readerFile()
public String readerFile(BufferedReader reader,String targetStr) throws IOException {
boolean matchingState = false;
StringBuffer result = new StringBuffer("");
int line = 1;
String tempStr = null;
if ((TooltipTextForArea.getHintText()).equals(targetStr)){
result.append("無匹配結果(空值匹配)!\n");
return result.toString();
}
while ((tempStr = reader.readLine()) != null){
System.out.println(line+" : "+tempStr);
if (tempStr.contains(targetStr)){
result.append("在第"+line+"行發現目標值! ["+tempStr+"]\n");
matchingState = true;
}
line++;
}
if (!matchingState){
result.append("無匹配結果.\n");
}
return result.toString();
}
到這裏,整個程序的開發就完成了,然後就是處理類的相互調用問題,創建Main類,聲明main方法,在main方法中調用
public class Main {
public static void main(String[] args) {
new Window();
}
}
四.依賴打入jar包
由於我們依賴了外部jar,IDE提供的直接打包模式沒法用,因爲IDE的直接打包模式沒法將依賴的jar封裝到項目中。因此我們需要使用maven命令進行打包。
1. 打包前的準備工作
1. 配置pom.xml
在pom.xml的build標籤下的pluginManagement標籤下的plugins標籤中加入如下代碼:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>top.woodenyi.core.Main</mainClass>
</manifest>
<manifestEntries>
<Class-Path>lib/*.jar</Class-Path>
</manifestEntries>
</archive>
<descriptors>
<!--assembly配置文件路徑,注意需要在項目中新建文件assembly/release.xml-->
<descriptor>${basedir}/assembly/release.xml</descriptor>
</descriptors>
</configuration>
</plugin>
如果發現此處的maven-assembly-plugin無法依賴,那麼在dependencies標籤下加入如下代碼:
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</dependency>
2. 在項目文件夾下新建assembly/release.xml文件
assembly/release.xml文件配置如下:
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>release</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>runtime</scope>
</dependencySet>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>system</scope>
</dependencySet>
</dependencySets>
</assembly>
這些準備工作做好了我們就可以開始打包了。
2. 使用mvn package assembly:single命令進行打包
我這裏使用的是Windows PowerShell進行操作的
1. 進入項目文件夾下
cd D:\IDEAworkspeace\matching\
圖4.2.1
2.執行mvn package assembly:single命令
mvn package assembly:single
如果出現圖4.2.2所示,則表示執行成功
3.檢查項目下的target文件夾
ls .\target
查看是否如圖4.2.3所示出現3個jar包
如果出現三個jar包,說明你就可以準備處理成可執行文件了。
注意:
matching-1.0-SNAPSHOT.jar這個jar包是不包含依賴jar包的。剩下兩個都是包含依賴jar包的,再處理成可執行問時任選其中一個。
五.jar包處理成可執行文件(.exe文件)
1.準備工作
安裝並激活exe4j,你可以從官網下載也可以用我提供的安裝包。提供一個可以使用的激活碼(PS:本來想提供我自己購買的激活碼,但是實力他不允許啊,所以大家還是自己掏銀子支持正版卅~):
安裝完畢後先激活,如圖5.1.1
2.將jar包處理成可執行文件
這裏比較繁瑣,我直接上圖;
到這裏以後全點擊Next即可,等待程序運行完畢就可以在你設置的輸出文件夾下找到相應的.exe文件了。
六.結束語
雖然這不是一次很舒服的開發過程,但是也給我帶來了些許快樂和成就感。希望大家在日後的工作和學習中都能找到快樂和成就感。畢竟快樂最重要嘛,其他的事情可以往後推一推。
哦,對了,我會把源碼和exe4j打成一個壓縮包上傳(點這裏獲取源碼文件),有需要的小夥伴可以下載一下,雖然窗口畫得比較醜,但也是可以湊合着用的。
期待我們下篇博客見。😝😝😝
本作品採用知識共享署名 4.0 國際許可協議進行許可。