想给程序增加一个可视化界面。从学习java开始,就一直没有怎么接触过gui编程,gui也确实被妖魔化、边缘化的比较严重。
简单查看了一些资料,发现对图像化的软件十分感兴趣,有些无法自拔的趋势。
一篇关于GUI文章的大神如是写到:“会不能代表什么,但是不会就能代表什么了”。
但迫于时间,只好忍痛,草草收场,导致很多设想没有实现,很多细节也没有完善。
先谈一下对v0.0.3代码的改造。
为了实现进度条功能,在excelUtil中增加了一个excels属性,用来判断excel中需要操作的数据条数。
excelUtil.java 代码如下
package com.crick.excel2word.util; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import com.crick.excel2word.core.enumeration.OfficeFileType; public class ExcelUtil extends OfficeFileUtil { public ExcelUtil(String fullPath) { super(fullPath); } private int excels = 0; public int getExcels() { return excels; } public List<File> scanDirExcel(String dirPath) { return super.scanDir(dirPath,OfficeFileType.EXCEL_03_TYPE,OfficeFileType.EXCEL_07UP_TYPE); } public List<Map<String,Object>> extract() { List<Map<String,Object>> results = new ArrayList<Map<String,Object>>(); Workbook book; try { book = new HSSFWorkbook(new BufferedInputStream(new FileInputStream(getFile()))); Sheet sheet = book.getSheetAt(0); if (sheet.getLastRowNum() == 0) { return null; } this.excels = sheet.getLastRowNum(); List<String> keys = getKeyList(sheet.getRow(0)); for (int i=sheet.getFirstRowNum()+1; i <= sheet.getLastRowNum(); i++) { Map<String,Object> param = extractRow(sheet.getRow(i),keys); results.add(param); } } catch (Exception e) { e.printStackTrace(); } return results; } private Map<String,Object> extractRow(Row row,List<String> keys){ Map<String,Object> params = new HashMap<String,Object>(); for (int i=0; i<row.getLastCellNum(); i++) { if (keys.get(i) == null || keys.get(i) == "") { continue; } row.getCell(i).setCellType(Cell.CELL_TYPE_STRING); params.put("#{"+keys.get(i)+"}",row.getCell(i)); } return params; } /** * 第一行作为key,即mark标签名 * * @param row * @return */ private List<String> getKeyList(Row row) { List<String> keys = new ArrayList<String>(); for (int i=0; i<=row.getLastCellNum();i++) { if (row.getCell(i) != null) { row.getCell(i).setCellType(Cell.CELL_TYPE_STRING); } keys.add(row.getCell(i)==null?"":row.getCell(i).toString().toLowerCase()); } //如果未指定name标签,则默认第一列为生成的word文件名 if (!keys.contains("name")) { keys.set(0,"name"); } return keys; } }因为WordUtil是对单个word文件的操作,无法判断word文件的数量,所以将words属性放在Excel2Words类中,并提供getProgress方法获取进度百分比。
package com.crick.excel2word; import java.io.File; import java.util.List; import java.util.Map; import com.crick.excel2word.util.ExcelUtil; import com.crick.excel2word.util.WordUtil; public class Excel2Words { private static WordUtil wordUtil; private static ExcelUtil excelUtil; private static int words = 0; private static void init(String wordPath,String excelPath) { wordUtil = new WordUtil(wordPath); excelUtil = new ExcelUtil(excelPath); } public static void autoExport(String wordPath,String excelPath,String exportDir) { init(wordPath,excelPath); if (!exportDir.endsWith(File.separator)) { exportDir = exportDir.concat(File.separator); } List<Map<String,Object>> rowList = excelUtil.extract(); for (Map<String,Object> rowParam : rowList) { wordUtil.export(rowParam,exportDir,rowParam.get("#{name}").toString()); words++; } } public static int getProgress() { return words*100/excelUtil.getExcels(); } }
图形化界面是通过eclipse,基于SWF和JFace制作而成。附Eclipse相关插件地址:http://download.eclipse.org/windowbuilder/WB/release/R201309271200/4.3/
能力有限,只是实现了基本功能,而代码层面,应该也没有达到比较好的实现,所以只是贴出代码,不做讲解。
MainWin.java依赖于v0.0.3打包生成的excel2word-0.0.3-SNAPSHOT-jar-with-dependencies.jar,代码如下:
package gui; import org.eclipse.jface.action.CoolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.StatusLineManager; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.ApplicationWindow; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.ProgressBar; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import com.crick.excel2word.Excel2Words; public class MainWin extends ApplicationWindow { private String wordPath; private String excelPath; private String exportDir; private ProgressBar progressBar; private Text wordPathText; private Text excelPathText; private Text exportDirText; private void clear() { wordPath = ""; excelPath = ""; exportDir = ""; wordPathText.setText(""); excelPathText.setText(""); exportDirText.setText(""); progressBar.setSelection(0); progressBar.dispose(); } private void showProgress(Composite parent) { progressBar = new ProgressBar(parent,SWT.NONE); progressBar.setBounds(20,200,550,25); progressBar.setMinimum(0); progressBar.setMaximum(100); new Thread() { public void run() { getShell().getDisplay().asyncExec(new Runnable() { public void run() { while (progressBar.getSelection() < progressBar.getMaximum()) { try { progressBar.setSelection(Excel2Words.getProgress()); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } MessageDialog.openInformation(getShell(),"完成","word文件已经生成成功,请在" + exportDirText.getText() + "目录下查看。"); clear(); } }); } }.start(); } /** * Create the application window,*/ public MainWin() { super(null); addCoolBar(SWT.FLAT); addMenuBar(); addStatusLine(); } /** * Create contents of the application window. * @param parent */ @Override protected Control createContents(Composite parent) { final Composite container = new Composite(parent,SWT.NONE); wordPathText = new Text(container,SWT.H_SCROLL | SWT.CANCEL | SWT.CENTER); wordPathText.setEditable(false); wordPathText.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); wordPathText.setFont(new Font(Display.getCurrent(),"微软雅黑",11,SWT.NORMAL)); wordPathText.setText("word文件"); wordPathText.setBounds(20,30,505,25); Label label1 = new Label(container,SWT.SEPARATOR | SWT.VERTICAL); label1.setBounds(527,2,25); final FileDialog wordDialog = new FileDialog(getShell()); Button selectWordBtn = new Button(container,SWT.NONE); selectWordBtn.setBounds(530,40,25); selectWordBtn.setText("选择"); selectWordBtn.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { wordPath = wordDialog.open(); wordPathText.setText(wordPath); } }); excelPathText = new Text(container,SWT.H_SCROLL | SWT.CANCEL | SWT.CENTER); excelPathText.setEditable(false); excelPathText.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); excelPathText.setFont(new Font(Display.getCurrent(),SWT.NORMAL)); excelPathText.setText("excel文件"); excelPathText.setBounds(20,70,25); Label label2 = new Label(container,SWT.SEPARATOR | SWT.VERTICAL); label2.setBounds(527,25); final FileDialog excelDialog = new FileDialog(getShell()); Button selectExcelBtn = new Button(container,SWT.NONE); selectExcelBtn.setBounds(530,25); selectExcelBtn.setText("选择"); selectExcelBtn.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { excelPath = excelDialog.open(); excelPathText.setText(excelPath); } }); exportDirText = new Text(container,SWT.H_SCROLL | SWT.CANCEL | SWT.CENTER); exportDirText.setEditable(false); exportDirText.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); exportDirText.setFont(new Font(Display.getCurrent(),SWT.NORMAL)); exportDirText.setText("保存路径"); exportDirText.setBounds(20,110,25); Label label3 = new Label(container,SWT.SEPARATOR | SWT.VERTICAL); label3.setBounds(527,25); final DirectoryDialog exportDialog = new DirectoryDialog(getShell()); Button selectExportBtn = new Button(container,SWT.NONE); selectExportBtn.setBounds(530,25); selectExportBtn.setText("选择"); selectExportBtn.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { exportDir = exportDialog.open(); exportDirText.setText(excelPath); } }); Button button = new Button(container,SWT.CHECK); button.setBounds(370,140,15); button.setText("打包压缩"); Button startBtn = new Button(container,SWT.NONE); startBtn.setBounds(150,160,300,25); startBtn.setText("开 始"); startBtn.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { showProgress(container); Excel2Words.autoExport(wordPath,excelPath,exportDir); } }); return container; } /** * Create the menu manager. * @return the menu manager */ @Override protected MenuManager createMenuManager() { MenuManager menuManager = new MenuManager("menu"); return menuManager; } /** * Create the coolbar manager. * @return the coolbar manager */ @Override protected CoolBarManager createCoolBarManager(int style) { CoolBarManager coolBarManager = new CoolBarManager(style); return coolBarManager; } /** * Create the status line manager. * @return the status line manager */ @Override protected StatusLineManager createStatusLineManager() { StatusLineManager statusLineManager = new StatusLineManager(); return statusLineManager; } /** * Launch the application. * @param args */ public static void main(String args[]) { try { MainWin window = new MainWin(); //使 open() 阻塞,直到窗口关闭为止 window.setBlockOnOpen(true); window.open(); Display.getCurrent().dispose(); } catch (Exception e) { e.printStackTrace(); } } /** * Configure the shell. * @param newShell */ @Override protected void configureShell(Shell newShell) { super.configureShell(newShell); newShell.setText("Excel parse to Words"); } /** * Return the initial size of the window. */ @Override protected Point getInitialSize() { return new Point(600,360); } }
这时有一个问题:由于是通过eclipse直接创建的SWT/JFace项目,所以依赖了众多的eclipse插件的jar包文件。
怎么能判断出项目依赖了哪些jar包,筛选出必需的依赖包呢?
第一步:利用eclipse将项目打包成jar文件。
第二步:通过-verbose:class判断使用了哪些.class文件
java -jar -verbose:class excel2word-0.0.4.jar >>dependents.txt
因为v0.0.4只有一个java文件,否则,则需要把各功能都使用一遍,以此找到所有的依赖文件。
第四步:将依赖的jar文件复制到新目录内。
将这两步放在一起的原因是因为我们要通过程序实现,我直接遍历的eclipse的plugins目录,具体代码如下:
package util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; public class CopyDependentJar { public static void main(String[] args) throws IOException { String classTxt = readClassTxt(); File file = new File("D:\\eclipse_kepler\\plugins"); for (File f : file.listFiles()) { if (classTxt.contains(f.getName())) { copy(f,"D:\\cut\\dependents"); } } } private static String readClassTxt() throws IOException { File file = new File("D:\\cut\\dependents.txt"); BufferedReader re = new BufferedReader(new FileReader(file)); StringBuffer sb = new StringBuffer(); String line = re.readLine(); while (line != null) { sb.append(line); line = re.readLine(); } re.close(); return sb.toString(); } private static void copy(File srcFile,String outDirPath) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile)); File outDir = new File(outDirPath); if (!outDir.exists()) { outDir.mkdir(); } File outFile = new File(outDirPath + File.separator + srcFile.getName()); if (!outFile.exists()) { outFile.createNewFile(); } BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outFile)); byte[] chs = new byte[1024]; int len = bis.read(chs,chs.length); while(len != -1){ bos.write(chs,len); len = bis.read(chs,chs.length); } bos.close(); bis.close(); } }
将dependents目录下的文件和excel2word-0.0.3-SNAPSHOT-jar-with-dependencies.jar一起放入项目的lib目录下,添加依赖,ok,搞定。
原文链接:https://www.f2er.com/javaschema/285701.html