Java爬虫_爬虫项目

一:介绍:本文会介绍一个完整的爬虫项目,并打包成windows可执行程序
1.1、效果图:


image.png

1.2、抓取数据页面:


image.png

1.3、抓取结果:
image.png

二:开发:
2.1、创建一个Maven项目“demo”
2.2、pom.xml中添加项目依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cll</groupId>
    <artifactId>demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>net.sourceforge.htmlunit</groupId>
            <artifactId>htmlunit</artifactId>
            <version>2.27</version>
        </dependency>
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.8.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.10.1</version>
        </dependency>
        <dependency>
            <groupId>com.hynnet</groupId>
            <artifactId>jxl</artifactId>
            <version>2.6.12.1</version>
        </dependency>
    </dependencies>
</project>

2.3、创建如下类

1`、QYEmailHelper.java(爬取网页数据的主要工具类)
import CaililiangTools.ConfigHelper;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.select.Elements;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Properties;

public class QYEmailHelper {
    static WebClient webClient=new WebClient(BrowserVersion.CHROME);
    ArrayList<HashMap<String,String>> returnList = new ArrayList<HashMap<String,String>>();
    static String baseUrl ="";
    static  int num =1;
    ConfigHelper configHelper = new ConfigHelper();
    Properties properties=null;

    //浏览器初始化
    public void WebClientInit(){
        webClient.getCookieManager().setCookiesEnabled(true);//设置cookie是否可用
        webClient.getOptions().setActiveXNative(false);
        webClient.getOptions().setRedirectEnabled(true);// 启动客户端重定向
        webClient.getOptions().setCssEnabled(false);//禁用Css,可避免自动二次请求CSS进行渲染
        webClient.getOptions().setJavaScriptEnabled(true); // 启动JS
        webClient.getOptions().setUseInsecureSSL(true);//忽略ssl认证
        webClient.getOptions().setThrowExceptionOnScriptError(false);//运行错误时,不抛出异常
        webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
        webClient.setAjaxController(new NicelyResynchronizingAjaxController());// 设置Ajax异步
        webClient.getOptions().setMaxInMemory(50000);
        properties = configHelper.getEmailUserInfos();
    }

    public void closeWebClient(){
        webClient.close();
        webClient=new WebClient(BrowserVersion.CHROME);
    }

    //用户登录并返回收件箱的地址
    public String UserLogin(String url,String name,String password) throws Exception{
        url = url.replace("param=caill@primeton.com","param="+name);
        final HtmlPage page = webClient.getPage(url);
        System.err.println("查询中,请稍候");
        //TimeUnit.SECONDS.sleep(3);  //web请求数据需要时间,必须让主线程休眠片刻
        HtmlForm form=page.getForms().get(0);
        HtmlPasswordInput txtPwd = (HtmlPasswordInput)form.getInputByName("pp");//密码框
        txtPwd.setValueAttribute(password);//设置密码
        HtmlSubmitInput submit=(HtmlSubmitInput) form.getInputByValue("登录");
        final HtmlPage page2 = (HtmlPage) submit.click();//登录进入
        DomElement e =page2.getElementById("folder_1");
        HtmlPage page3 = webClient.getPage("https://mail.primeton.com"+e.getAttribute("href"));
        //TimeUnit.SECONDS.sleep(3);  //web请求数据需要时间,必须让主线程休眠片刻
        HtmlInlineFrame frame1 = (HtmlInlineFrame)page3.getElementById("mainFrame");
        String src = frame1.getAttribute("src");
        baseUrl="https://mail.primeton.com"+src;
        return "https://mail.primeton.com"+src;
    }

    //抓取Url中的数据
    public long getHtmlPage(String url,long startTime,long endTime) throws Exception{
        HashMap<String,String> returnMap = new HashMap<String,String>();
        long endTime2=0L;
        HtmlPage page = webClient.getPage(url);
        HtmlBody tbody = (HtmlBody) page.getBody();
        DomNodeList<HtmlElement> lists = tbody.getElementsByTagName("table");
        //System.out.println( page.asXml());
        for(HtmlElement he:lists){
            long time =0L;
            HashMap<String,String> results = new HashMap<String,String>();
            String xml = he.asXml();
            if(xml.startsWith("<table cellspacing=\"0\" class=") && xml.contains("<input totime=")){
                Document document = Jsoup.parse(xml);
                Elements es = document.getElementsByClass("cx");
                Elements es2 = document.getElementsByClass("black");
                for(Element e :es){
                    Node node =e.childNode(1);
                    time = Long.parseLong(node.attr("totime"));
                    endTime2 = time;
                    String email = node.attr("fa");
                    if(properties.containsKey(email)){
                        String value = properties.getProperty(email);
                        String[] vs = value.split("@@");
                        if(vs.length==2){
                            results.put("totime",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(time)));
                            results.put("unread",(node.attr("unread")).equalsIgnoreCase("true")?"已读":"未读");
                            results.put("name",vs[1]);
                            results.put("mail",email);
                            results.put("dept",vs[0]);
                        }else{
                            results.put("totime",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(time)));
                            results.put("unread",(node.attr("unread")).equalsIgnoreCase("true")?"已读":"未读");
                            results.put("name",node.attr("fn"));
                            results.put("mail",email);
                            results.put("dept","");
                        }
                    }else{
                        results.put("totime",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(time)));
                        results.put("unread",(node.attr("unread")).equalsIgnoreCase("true")?"已读":"未读");
                        results.put("name",node.attr("fn"));
                        results.put("mail",email);
                        results.put("dept","");
                    }
                }
                for(Element e :es2){
                    results.put("title",e.ownText());
                }
                if(time<=endTime && startTime<=time){
                    returnList.add(results);
                }
            }
        };
        return endTime2;
    }

    public void grabData(String url,long startTime,long endTime) throws Exception{
        long endTime2 = getHtmlPage(url,startTime,endTime);
        if(endTime2>startTime){
            String nextPageUrl=baseUrl.replace("page=0","page="+num);
            num++;
            grabData(nextPageUrl,startTime,endTime);
        }
    }

    public int exportData(long startTime,long endTime,String name,String password){
        int returnInt = 0;
        this.WebClientInit();
        String webUrl="https://mail.primeton.com/cgi-bin/loginpage?t=logindomain&s=logout&f=biz&param=caill@primeton.com";
        String url1 = null;
        try {
            url1 = this.UserLogin(webUrl,name,password);
            grabData(url1,startTime,endTime);
            ExcelHelper excelHelper = new ExcelHelper();
            excelHelper.exportExcel(this.returnList);
            num=1;
            baseUrl ="";
            returnList = new ArrayList<HashMap<String,String>>();
            closeWebClient();
        } catch (Exception e) {
            returnInt = 1;
            num=1;
            baseUrl ="";
            returnList = new ArrayList<HashMap<String,String>>();
            closeWebClient();
        }
        return returnInt;
    }
}

2、ExcelHelper.java(导出Excel文件的主要工具类)
import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

import javax.swing.filechooser.FileSystemView;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

public class ExcelHelper {
    public void exportExcel(ArrayList<HashMap<String,String>> list){
        String dbname = "";
        String path =null;

        String row = "部门,姓名,邮箱,时间,是否阅读,主题";
        String[] rows = row.split(",");
        ArrayList fields = null;
        ArrayList data = new ArrayList();
        ArrayList heard = new ArrayList();
        ArrayList datas = new ArrayList();
        for(String r:rows){
            data.add(r);
        }
        datas.add(data);

        for(HashMap<String,String> hm:list){
            ArrayList data2 = new ArrayList();
            data2.add(hm.get("dept"));
            data2.add(hm.get("name"));
            data2.add(hm.get("mail"));
            data2.add(hm.get("totime"));
            data2.add(hm.get("unread"));
            data2.add(hm.get("title"));
            datas.add(data2);
        }

        FileSystemView fsv = FileSystemView.getFileSystemView();
        File f=fsv.getHomeDirectory(); //这便是读取桌面路径的方法了
        path = f.getPath();
        System.out.println(path);
        OutputStream out = null ; // 准备好一个输出的对象
        if(!f.exists()){f.mkdir();}
        String filePath = path+"/周报上报情况"+new SimpleDateFormat("yyyy-MM-dd_HH_mm_ss").format(new Date(System.currentTimeMillis()))+".xls";
        File outFile = new File(filePath);
        try {
            out = new FileOutputStream(filePath); // 通过对象多态性,进行实例化
            // 创建Excel工作薄
            WritableWorkbook workbook = Workbook.createWorkbook(out);

            int length = datas.size();

            // 添加第一个工作表并设置第一个Sheet的名字
            WritableSheet sheet = workbook.createSheet("周报详情", 1);
            Label label;
            heard=(ArrayList)datas.get(0);
            for(int i2 = 0;i2<heard.size();i2++){
                //String aaaaaaa= (heard.get(i2)).toString();
                label = new Label(i2,0,(String) heard.get(i2));
                sheet.addCell(label);
            }
            ArrayList filed = new ArrayList();

            for(int i3=1;i3<length;i3++){
                filed = (ArrayList)datas.get(i3);
                for(int i4 = 0;i4<filed.size();i4++){
                    label = new Label(i4,i3,(String) filed.get(i4));
                    sheet.addCell(label);
                }
            }

            // 写入数据
            workbook.write();
            // 关闭文件
            workbook.close();
            out.close();

        } catch (Exception  e) {
            e.printStackTrace();
        }
    }
}

3、MyFrame.java(widows窗口类)
import CaililiangTools.ConfigHelper;
import DateSelector.DateSelector;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;

public class MyFrame extends JFrame{
    ConfigHelper confighelper = new ConfigHelper();

    JPanel panel = new JPanel();
    JTextField name = new JTextField();
    JPasswordField password = new JPasswordField();
    JButton startDate = new DateSelector();
    JButton endDate = new DateSelector();
    JButton button1 = new JButton("一键导出");
    JLabel label = new JLabel("提示:导出数据需要一些时间,勿频繁点击按钮");
    JButton button2 = new JButton("帮助");
    int width = Toolkit.getDefaultToolkit().getScreenSize().width;
    int height =Toolkit.getDefaultToolkit().getScreenSize().height;
    public MyFrame(){
        this.setTitle("普元企业邮箱助手");
        this.setSize(355,340);
        this.setResizable(false);
        this.setLocation(width/2-176,height/2-170);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        this.add(panel);
        panel.setLayout(null);
        JLabel label1 = new JLabel("账号:");
        JLabel label2 = new JLabel("密码:");
        JLabel label3 = new JLabel("开始时间:");
        JLabel label4 = new JLabel("截止时间:");
        label1.setBounds(10,20,80,25);
        label2.setBounds(10,70,80,25);
        label3.setBounds(10,120,80,25);
        label4.setBounds(10,170,80,25);
        panel.add(label1);
        panel.add(label2);
        panel.add(label3);
        panel.add(label4);
        name.setBounds(100,20,240,25);
        password.setBounds(100,70,240,25);
        startDate.setBounds(100,120,240,25);
        endDate.setBounds(100,170,240,25);
        panel.add(name);
        panel.add(password);
        panel.add(startDate);
        panel.add(endDate);
        HashMap<String,String> user = confighelper.getUserInfo();
        name.setText(user.get("userName"));
        password.setText(user.get("passWord"));
        button1.setBounds(115,220,100,30);
        button1.setBackground(Color.CYAN);
        button1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                SimpleDateFormat sDateFormat=new SimpleDateFormat("yyyy年MM月dd日   HH时mm分ss秒");
                String name2 = name.getText();
                String password2 = password.getText();
                long startTime = 0L;
                long endTime = 0L;
                try {
                    Date date1=sDateFormat.parse(startDate.getText());
                    Date date2=sDateFormat.parse(endDate.getText());
                    startTime = date1.getTime();
                    endTime = date2.getTime();
                } catch(ParseException px) {
                    px.printStackTrace();
                }
                try {
                    QYEmailHelper helper = new QYEmailHelper();
                    int out = helper.exportData(startTime,endTime,name2,password2);
                    if(out==1){
                        label.setText("账号密码错误,无法登陆");
                    }else{
                        label.setText("数据导出成功");
                    }
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
        });
        panel.add(button1);
        label.setBounds(10,270,300,30);
        panel.add(label);
        button2.setBounds(285,270,60,30);
        panel.add(button2);
        button2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JFrame frame1 = new JFrame("帮助手册");
                frame1.setSize(355,340);
                frame1.setResizable(false);
                frame1.setLocation(width/2+176,height/2);
                JTextArea jta = new JTextArea(10, 15);
                jta.setTabSize(4);
                jta.setFont(new Font("宋体", Font.PLAIN, 16));
                jta.setLineWrap(true);// 激活自动换行功能
                jta.setWrapStyleWord(false);// 激活断行不断字功能
                jta.setText("本工具使用注意事项:   \n1、UserInfo.properties文件和EmaiUserInfos.properties文件必须放在windows桌面才生效;\n2、UserInfo.properties文件存放的是登录人信息,有该文件之后每次启动程序可以不用输账号密码;  \n3、EmaiUserInfos.properties文件存放的是邮箱联系人的信息,可以辅助组装数据;  \n4、导出数据需要一些时间,切勿频繁点击'一键导出'按钮,否则可能导致死机;  \n5、如有其它问题请联系微信(caililiangcaililiang)或邮箱(caill@primeton.com)");
                //jta.setBackground(Color.pink);
                frame1.add(jta);
                frame1.setVisible(true);
            }
        });

        this.setVisible(true);
    }
}

4、MyEntrance.java(程序入口类)
public class MyEntrance {
    public static void main(String[] args){
        new MyFrame();
    }
}

5、DateSelector.java(windows窗口中的日期选择控件)
package DateSelector;

import java.util.Date;
import java.util.Calendar;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.awt.Color;
import java.awt.Font;
import java.awt.Point;
import java.awt.Dimension;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Frame;


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; //import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JSpinner;
import javax.swing.JSpinner.NumberEditor;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.swing.border.LineBorder;


public class DateSelector extends JButton {


      private DateChooser dateChooser = null;


      private String preLabel = "";


      public DateSelector() {
            this(getNowDate());
      }


      public DateSelector(SimpleDateFormat df, String dateString) {
            this();
            setText(df, dateString);
      }


      public DateSelector(Date date) {
            this("", date);
      }


      public DateSelector(String preLabel, Date date) {
            if (preLabel != null)
                  this.preLabel = preLabel;
            setDate(date);
            setBorder(null);
            setCursor(new Cursor(Cursor.HAND_CURSOR));
            super.addActionListener(new ActionListener() {
                  public void actionPerformed(ActionEvent e) {
                        if (dateChooser == null)
                              dateChooser = new DateChooser();
                        Point p = getLocationOnScreen();
                        p.y = p.y + 30;
                        dateChooser.showDateChooser(p);
                  }
            });
      }


      private static Date getNowDate() {
            return Calendar.getInstance().getTime();
      }


      private static SimpleDateFormat getDefaultDateFormat() {
            return new SimpleDateFormat("yyyy年MM月dd日   HH时mm分ss秒");
      }


      public void setText(String s) {
            Date date;
            try {
                  date = getDefaultDateFormat().parse(s);
            } catch (ParseException e) {
                  date = getNowDate();
            }
            setDate(date);
      }


      public void setText(SimpleDateFormat df, String s) {
            Date date;
            try {
                  date = df.parse(s);
            } catch (ParseException e) {
                  date = getNowDate();
            }
            setDate(date);
      }


      public void setDate(Date date) {
            super.setText(preLabel + getDefaultDateFormat().format(date));
      }


      public Date getDate() {
            String dateString = getText().substring(preLabel.length());
            try {
                  return getDefaultDateFormat().parse(dateString);
            } catch (ParseException e) {
                  return getNowDate();
            }


      }


      // 覆盖父类的方法使之无效
              public void addActionListener(ActionListener listener) {
      }


      private class DateChooser extends JPanel implements ActionListener,
                  ChangeListener {
            int startYear = 1980; // 默认【最小】显示年份
            int lastYear = 2050; // 默认【最大】显示年份
            int width = 200; // 界面宽度
            int height = 200; // 界面高度


            Color backGroundColor = Color.gray; // 底色
            // 月历表格配色----------------//
            Color palletTableColor = Color.white; // 日历表底色
            Color todayBackColor = Color.orange; // 今天背景色
            Color weekFontColor = Color.blue; // 星期文字色
            Color dateFontColor = Color.black; // 日期文字色
            Color weekendFontColor = Color.red; // 周末文字色


            // 控制条配色------------------//
            Color controlLineColor = Color.blue; // 控制条底色
            Color controlTextColor = Color.white; // 控制条标签文字色


            Color rbFontColor = Color.white; // RoundBox文字色
            Color rbBorderColor = Color.red; // RoundBox边框色
            Color rbButtonColor = Color.pink; // RoundBox按钮色
            Color rbBtFontColor = Color.red; // RoundBox按钮文字色


            JDialog dialog;
            JSpinner yearSpin;
            JSpinner monthSpin;
            JSpinner hourSpin;
            JSpinner minuteSpin;
            JSpinner secondSpin;
            JButton[][] daysButton = new JButton[6][7];


            DateChooser() {


                  setLayout(new BorderLayout());
                  setBorder(new LineBorder(backGroundColor, 2));
                  setBackground(backGroundColor);


                  /*上中下布局*/
                  JPanel topYearAndMonth = createYearAndMonthPanal();
                  add(topYearAndMonth, BorderLayout.NORTH);
                  JPanel centerWeekAndDay = createWeekAndDayPanal();
                  add(centerWeekAndDay, BorderLayout.CENTER);
                  JPanel southMinAndSec = createMinuteAndsecondPanal();
                  add(southMinAndSec, BorderLayout.SOUTH);
            }


            private JPanel createYearAndMonthPanal() {
                  Calendar c = getCalendar();
                  int currentYear = c.get(Calendar.YEAR);//年
                  int currentMonth = c.get(Calendar.MONTH) + 1;//月


                  JPanel result = new JPanel();
                  result.setLayout(new FlowLayout());
                  result.setBackground(controlLineColor);


                  yearSpin = new JSpinner(new SpinnerNumberModel(currentYear,
                                                  startYear, lastYear, 1));
                  yearSpin.setPreferredSize(new Dimension(48, 20));
                  yearSpin.setName("Year");
                  yearSpin.setEditor(new JSpinner.NumberEditor(yearSpin, "####"));
                  yearSpin.addChangeListener(this);
                  result.add(yearSpin);


                  JLabel yearLabel = new JLabel("年");
                  yearLabel.setForeground(controlTextColor);
                  result.add(yearLabel);


                  monthSpin = new JSpinner(new SpinnerNumberModel(currentMonth, 1,
                                                  12, 1));
                  monthSpin.setPreferredSize(new Dimension(35, 20));
                  monthSpin.setName("Month");
                  monthSpin.addChangeListener(this);
                  result.add(monthSpin);


                  JLabel monthLabel = new JLabel("月");
                  monthLabel.setForeground(controlTextColor);
                  result.add(monthLabel);


                  return result;
            }


            private JPanel createWeekAndDayPanal() {
                  String colname[] = { "日", "一", "二", "三", "四", "五", "六" };
                  JPanel result = new JPanel();
                  // 设置固定字体,以免调用环境改变影响界面美观
                  result.setFont(new Font("宋体", Font.PLAIN, 12));
                  result.setLayout(new GridLayout(7, 7));
                  result.setBackground(Color.white);
                  JLabel cell;


                  for (int i = 0; i < 7; i++) {
                        cell = new JLabel(colname[i]);
                        cell.setHorizontalAlignment(JLabel.RIGHT);
                        if (i == 0 || i == 6)
                              cell.setForeground(weekendFontColor);
                        else
                              cell.setForeground(weekFontColor);
                        result.add(cell);
                  }


                  int actionCommandId = 0;
                  for (int i = 0; i < 6; i++)
                        for (int j = 0; j < 7; j++) {
                              JButton numberButton = new JButton();
                              numberButton.setBorder(null);
                              numberButton.setHorizontalAlignment(SwingConstants.RIGHT);
                              numberButton.setActionCommand(String
                                                                  .valueOf(actionCommandId));
                              numberButton.addActionListener(this);
                              numberButton.setBackground(palletTableColor);
                              numberButton.setForeground(dateFontColor);
                              if (j == 0 || j == 6)
                                    numberButton.setForeground(weekendFontColor);
                              else
                                    numberButton.setForeground(dateFontColor);
                              daysButton[i][j] = numberButton;
                              result.add(numberButton);
                              actionCommandId++;
                        }


                  return result;
            }


            private JPanel createMinuteAndsecondPanal() {
                  Calendar c = getCalendar();


                  int currentHour = c.get(Calendar.HOUR_OF_DAY);//时
                  int currentMin = c.get(Calendar.MINUTE);//分
                  int currentSec = c.get(Calendar.SECOND);//秒


                  JPanel result = new JPanel();
                  result.setLayout(new FlowLayout());
                  result.setBackground(controlLineColor);


                  hourSpin = new JSpinner(new SpinnerNumberModel(currentHour, 0, 23,1));
                  hourSpin.setPreferredSize(new Dimension(35, 20));
                  hourSpin.setName("Hour");
                  hourSpin.addChangeListener(this);
                  result.add(hourSpin);


                  JLabel hourLabel = new JLabel("时");
                  hourLabel.setForeground(controlTextColor);
                  result.add(hourLabel);
                   
                  minuteSpin = new JSpinner(new SpinnerNumberModel(currentMin, 0, 59, 1));
                  minuteSpin.setPreferredSize(new Dimension(35, 20));
                  minuteSpin.setName("Minute");
                  minuteSpin.addChangeListener(this);
                  result.add(minuteSpin);


                  JLabel minuteLabel = new JLabel("分");
                  minuteLabel.setForeground(controlTextColor);
                  result.add(minuteLabel);
                   
                  secondSpin = new JSpinner(new SpinnerNumberModel(currentSec, 0, 59,1));
                  secondSpin.setPreferredSize(new Dimension(35, 20));
                  secondSpin.setName("Second");
                  secondSpin.addChangeListener(this);
                  result.add(secondSpin);


                  JLabel secondLabel = new JLabel("秒");
                  secondLabel.setForeground(controlTextColor);
                  result.add(secondLabel);


                  return result;
            }
             
            private JDialog createDialog(Frame owner) {
                  JDialog result = new JDialog(owner, "日期时间选择", true);
                  result.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
                  result.getContentPane().add(this, BorderLayout.CENTER);
                  result.pack();
                  result.setSize(width, height);
                  return result;
            }


            void showDateChooser(Point position) {
                  Frame owner = (Frame) SwingUtilities
                              .getWindowAncestor(DateSelector.this);
                  if (dialog == null || dialog.getOwner() != owner)
                        dialog = createDialog(owner);
                  dialog.setLocation(getAppropriateLocation(owner, position));
                  flushWeekAndDay();
                  dialog.show();
            }


            Point getAppropriateLocation(Frame owner, Point position) {
                  Point result = new Point(position);
                  Point p = owner.getLocation();
                  int offsetX = (position.x + width) - (p.x + owner.getWidth());
                  int offsetY = (position.y + height) - (p.y + owner.getHeight());


                  if (offsetX > 0) {
                        result.x -= offsetX;
                  }


                  if (offsetY > 0) {
                        result.y -= offsetY;
                  }


                  return result;


            }


            private Calendar getCalendar() {
                  Calendar result = Calendar.getInstance();
                  result.setTime(getDate());
                  return result;
            }


            private int getSelectedYear() {
                  return ((Integer) yearSpin.getValue()).intValue();
            }


            private int getSelectedMonth() {
                  return ((Integer) monthSpin.getValue()).intValue();
            }


            private int getSelectedHour() {
                  return ((Integer) hourSpin.getValue()).intValue();
            }
             
            private int getSelectedMinute() {
                  return ((Integer) minuteSpin.getValue()).intValue();
            }
             
            private int getSelectedSecond() {
                  return ((Integer) secondSpin.getValue()).intValue();
            }


            private void dayColorUpdate(boolean isOldDay) {
                  Calendar c = getCalendar();
                  int day = c.get(Calendar.DAY_OF_MONTH);
                  c.set(Calendar.DAY_OF_MONTH, 1);
                  int actionCommandId = day - 2 + c.get(Calendar.DAY_OF_WEEK);
                  int i = actionCommandId / 7;
                  int j = actionCommandId % 7;
                  if (isOldDay)
                        daysButton[i][j].setForeground(dateFontColor);
                  else
                        daysButton[i][j].setForeground(todayBackColor);
            }


            private void flushWeekAndDay() {
                  Calendar c = getCalendar();
                  c.set(Calendar.DAY_OF_MONTH, 1);
                  int maxDayNo = c.getActualMaximum(Calendar.DAY_OF_MONTH);
                  int dayNo = 2 - c.get(Calendar.DAY_OF_WEEK);
                  for (int i = 0; i < 6; i++) {
                        for (int j = 0; j < 7; j++) {
                              String s = "";
                              if (dayNo >= 1 && dayNo <= maxDayNo)
                                    s = String.valueOf(dayNo);
                              daysButton[i][j].setText(s);
                              dayNo++;
                        }
                  }
                  dayColorUpdate(false);
            }


            public void stateChanged(ChangeEvent e) {
                  JSpinner source = (JSpinner) e.getSource();
                  Calendar c = getCalendar();
                  if (source.getName().equals("Hour")) {
                        c.set(Calendar.HOUR_OF_DAY, getSelectedHour());
                        setDate(c.getTime());
                        return;
                  }
                  else if(source.getName().equals("Minute")){
                  c.set(Calendar.MINUTE, getSelectedMinute());
                        setDate(c.getTime());
                        return;
                  }
                  else if(source.getName().equals("Second")){
                  c.set(Calendar.SECOND, getSelectedSecond());
                        setDate(c.getTime());
                        return;
                  }


                  dayColorUpdate(true);


                  if (source.getName().equals("Year"))
                        c.set(Calendar.YEAR, getSelectedYear());
                  else
                        // (source.getName().equals("Month"))
                        c.set(Calendar.MONTH, getSelectedMonth() - 1);
                  setDate(c.getTime());
                  flushWeekAndDay();
            }


            public void actionPerformed(ActionEvent e) {
                  JButton source = (JButton) e.getSource();
                  if (source.getText().length() == 0) return;
                  dayColorUpdate(true);
                  source.setForeground(todayBackColor);
                  int newDay = Integer.parseInt(source.getText());
                  Calendar c = getCalendar();
                  c.set(Calendar.DAY_OF_MONTH, newDay);
                  setDate(c.getTime());
            }


      }


}

6、ConfigHelper.java(配置文件获取类)
package CaililiangTools;

import java.io.*;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Properties;

public class ConfigHelper {
    public HashMap<String,String> getUserInfo() {
        HashMap<String,String> returnMap = new HashMap<String,String>();
        try{
            Properties properties = new Properties();
            InputStream in = new BufferedInputStream(new FileInputStream("C:\\Users\\Administrator\\Desktop\\UserInfo.properties"));
            properties.load(new InputStreamReader(in, "utf-8"));
            String userName = properties.getProperty("userName");
            String passWord = properties.getProperty("passWord");
            returnMap.put("userName",userName);
            returnMap.put("passWord",passWord);
        }catch (IOException e){
            System.err.println("UserInfo.properties文件读取失败");
            System.err.println("UserInfo.properties文件必须放在windows桌面上");
        }
        return returnMap;
    }
    public Properties getEmailUserInfos() {
        Properties properties=null;
        HashMap<String,String> returnMap = new HashMap<String,String>();
        try{
            properties = new Properties();
            InputStream in =  new BufferedInputStream(new FileInputStream("C:\\Users\\Administrator\\Desktop\\EmaiUserInfos.properties"));
            properties.load(new InputStreamReader(in, "utf-8"));
        }catch (IOException e){
            System.err.println("EmaiUserInfos.properties文件读取失败");
            System.err.println("EmaiUserInfos.properties文件必须放在windows桌面上");
        }
        return properties;
    }
}

项目结构图:


image.png

三、项目导出可执行jar包
3.1、setting配置


image.png
image.png
image.png
image.png

3.2、编译


image.png
image.png
image.png

四、jar包装成EXE可执行程序(exe4j工具)
参照我的另一篇文章:https://www.jianshu.com/p/bfad27d7812d

五、exe文件打包成可安装程序(inno setup工具)
参照我的另一篇文章:https://www.jianshu.com/p/63b2605ee2b4

六、项目下载地址:
链接:https://pan.baidu.com/s/18mhhNw1qJ2yQVKX9rZamdQ
提取码:l7jz

如有问题或有想相互学习交流的,可以联系本人(邮箱:18986837482@163.com,微信:caililiangcaililiang,QQ:785553790)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,056评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,842评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,938评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,296评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,292评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,413评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,824评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,493评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,686评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,502评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,553评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,281评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,820评论 3 305
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,873评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,109评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,699评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,257评论 2 341

推荐阅读更多精彩内容