精华内容
下载资源
问答
  • Android读写SQLite数据库并导出SQLite数据写入到Excel表中 需要先引入Apache POI的jar包到Android Studio中的libs,以扩展Android支持读写Excel表格。参考我的另一篇文章: 《Java读取Excel数据:基于Apache POI...

    Android读写SQLite数据库并导出SQLite数据写入到Excel表中

    需要先引入Apache POI的jar包到Android Studio中的libs,以扩展Android支持读写Excel表格。参考我的另一篇文章:

    《Java读取Excel数据:基于Apache POI(一)》链接:
    https://blog.csdn.net/zhangphil/article/details/85302347
    引入jar包后,Android项目工程结构如图所示:

    Android因为要读写SQLite数据库,事先需要先准备一个SQLiteOpenHelper,MySQLiteOpenHelper.java:

    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.support.annotation.Nullable;
    
    public class MySQLiteOpenHelper extends SQLiteOpenHelper {
    
        //数据库名称。
        public static final String DATABASE_NAME = "zhangphil.db";
    
        //数据库版本号。
        public static int DATABASE_VERSION = 1;
    
        private static MySQLiteOpenHelper helper;
    
        //表名。
        public static final String TABLE_NAME = "Student";
    
        public static final String STUDENT_ID = "id";
        public static final String STUDENT_NAME = "name";
        public static final String STUDENT_GENDER = "gender";
        public static final String STUDENT_AGE = "age";
    
        //创建数据库表的SQL语句。
        private String sql_create_table = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" + STUDENT_ID + " integer primary key autoincrement," + STUDENT_NAME + " varchar(60)," + STUDENT_GENDER + " varchar(1)," + STUDENT_AGE + " int)";
    
        public static MySQLiteOpenHelper getInstance(Context context) {
            if (helper == null) {
                helper = new MySQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
            }
    
            return helper;
        }
    
        public MySQLiteOpenHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
            super(context, name, factory, version);
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            //创建数据库的表,如果不存在。
            db.execSQL(sql_create_table);
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    
        }
    }
    

     

    然后就可以直接在Android程序中读写SQLite数据库并把SQLite数据库中数据导出,写入到Excel表中去:

    import android.content.ContentValues;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.os.Bundle;
    import android.os.Environment;
    import android.support.v7.app.AppCompatActivity;
    
    import org.apache.poi.hssf.usermodel.HSSFRow;
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    
    import java.io.File;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 本例数据样本容量很小,简单期间放到UI主线程中直接读写SQLite数据库。
     * 实际的开发中不允许这样在UI主线程读写SQLite数据库,应该把读写数据库操作的代码后台线程化。
     *
     *
     * 本例出于演示期间,把写文件操作放到UI主线了。事实上读写文件操作也应该放到非UI线程中处理。
     *
     *
     * 另外:
     * HSSFWorkbook:操作Excel 97-2003版本,Excel扩展名是.xls。
     * XSSFWorkbook:操作Excel 2007以后版本,Excel扩展名是.xlsx。
     * 从POI 3.8开始,提供了一种基于XSSF的低内存占用的SXSSF。
     *
     */
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            SQLiteDatabase sqLiteDatabase = MySQLiteOpenHelper.getInstance(this).getWritableDatabase();
    
            ContentValues contentValues1 = getContentValues("zhang", "男", 18);
            ContentValues contentValues2 = getContentValues("phil", "男", 19);
    
            //往SQLite数据库中插入两条数据。
            sqLiteDatabase.insert(MySQLiteOpenHelper.TABLE_NAME, null, contentValues1);
            sqLiteDatabase.insert(MySQLiteOpenHelper.TABLE_NAME, null, contentValues2);
            sqLiteDatabase.close();
    
            //从SQLite数据库中读出数据。
            List<Student> students = query(MySQLiteOpenHelper.getInstance(this).getReadableDatabase());
    
            HSSFWorkbook mWorkbook = new HSSFWorkbook();
            HSSFSheet mSheet = mWorkbook.createSheet(MySQLiteOpenHelper.TABLE_NAME);
            createExcelHead(mSheet);
    
            for (Student student : students) {
                //System.out.println(student.id + "," + student.name + "," + student.gender + "," + student.age);
                createCell(student.id, student.name, student.gender, student.age, mSheet);
            }
    
            File xlsFile = new File(Environment.getExternalStorageDirectory(), "excel.xls");
            try {
                if (!xlsFile.exists()) {
                    xlsFile.createNewFile();
                }
                mWorkbook.write(xlsFile);// 或者以流的形式写入文件 mWorkbook.write(new FileOutputStream(xlsFile));
                mWorkbook.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        private ContentValues getContentValues(String name, String gender, int age) {
            ContentValues contentValues = new ContentValues();
            contentValues.put(MySQLiteOpenHelper.STUDENT_NAME, name);
            contentValues.put(MySQLiteOpenHelper.STUDENT_GENDER, gender);
            contentValues.put(MySQLiteOpenHelper.STUDENT_AGE, age);
            return contentValues;
        }
    
        //查询SQLite数据库。读出所有数据内容。
        private List<Student> query(SQLiteDatabase db) {
            List<Student> students = null;
    
            Cursor cursor = db.rawQuery("SELECT * FROM " + MySQLiteOpenHelper.TABLE_NAME, null);
            if (cursor != null && cursor.getCount() > 0) {
    
                students = new ArrayList<>();
    
                while (cursor.moveToNext()) {
                    Student student = new Student();
    
                    student.id = cursor.getInt(cursor.getColumnIndex(MySQLiteOpenHelper.STUDENT_ID));
                    student.name = cursor.getString(cursor.getColumnIndex(MySQLiteOpenHelper.STUDENT_NAME));
                    student.gender = cursor.getString(cursor.getColumnIndex(MySQLiteOpenHelper.STUDENT_GENDER));
                    student.age = cursor.getInt(cursor.getColumnIndex(MySQLiteOpenHelper.STUDENT_AGE));
    
                    students.add(student);
                }
    
                cursor.close();
            }
    
            db.close();
    
            return students;
        }
    
        //数据容器,装载从数据库中读出的数据内容。
        private class Student {
            public int id;
            public String name;
            public String gender;
            public int age;
        }
    
        // 创建Excel标题行,第一行。
        private void createExcelHead(HSSFSheet mSheet) {
            HSSFRow headRow = mSheet.createRow(0);
            headRow.createCell(0).setCellValue(MySQLiteOpenHelper.STUDENT_ID);
            headRow.createCell(1).setCellValue(MySQLiteOpenHelper.STUDENT_NAME);
            headRow.createCell(2).setCellValue(MySQLiteOpenHelper.STUDENT_GENDER);
            headRow.createCell(3).setCellValue(MySQLiteOpenHelper.STUDENT_AGE);
        }
    
        // 创建Excel的一行数据。
        private static void createCell(int id, String name, String gender, int age, HSSFSheet sheet) {
            HSSFRow dataRow = sheet.createRow(sheet.getLastRowNum() + 1);
    
            dataRow.createCell(0).setCellValue(id);
            dataRow.createCell(1).setCellValue(name);
            dataRow.createCell(2).setCellValue(gender);
            dataRow.createCell(3).setCellValue(age);
        }
    }

     

    不要忘记授权App拥有读写外部存储器的权限:

     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

     

    程序运行后导出的excel.xls文件位于外部存储器的根目录下,打开该文件,显示:

    展开全文
  • 说明:由于公司项目需求,需要将数据导出成Excel表格,并且可选择导出项,选择合计项,可下载。项目使用的Spring+Mybatis+SpringMVC框架,...流程:导出按钮触发查找数据库表controller传递过去表名→查出来后展现在

    说明:由于公司项目需求,需要将数据导出成Excel表格,并且可选择导出项,选择合计项,可下载。项目使用的Spring+Mybatis+SpringMVC框架,利用Apache POI导出Excel。因为需要导出的表格比较多,当然需要一个通用的工具类,思路是通过查找数据库注释当作表头,减少工作量。POI具体使用请自行百度。

    • 流程
      导出按钮触发查找数据库表controller并传递过去表名→查出来后展现在通用显示导出export_select.jsp→选择导出项与合计项后调用相应controller查找数据并调用ExportExcelUtil.java

    • 导出excel工具类ExportExcelUtil.java

    package com.rixin.common.util;
    
    import java.io.OutputStream;
    import java.lang.reflect.Method;
    import java.net.URLEncoder;
    import java.util.Collection;
    import java.util.Iterator;
    
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.poi.hssf.usermodel.HSSFCell;
    import org.apache.poi.hssf.usermodel.HSSFCellStyle;
    import org.apache.poi.hssf.usermodel.HSSFRow;
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.ss.usermodel.Font;
    
    /**
     * 基于POI的javaee导出Excel工具类
     * 
     * @author wjmisaboy@gmail.com
     * @see POI
     */
    public class ExportExcelUtil {
        /**
         * 
         * @param response
         *            请求
         * @param fileName
         *            文件名 如:"学生表"
         * @param excelHeaderArray
         *            excel表头数组,存放"姓名#name"格式字符串,"姓名"为excel标题行, "name"为对象字段名
         * @param dataList
         *            数据集合,需与表头数组中的字段名一致,并且符合javabean规范
         * @param total
         *            需要合计项字符串,","分割
         * @return 返回一个HSSFWorkbook
         * @throws Exception
         */
        public static <T> HSSFWorkbook export(HttpServletResponse response, String fileName, String excelHeader,Collection<T> dataList, String total) throws Exception {
            String[] excelHeaderArray = null;//表头数组
            String[] totalArray = null;//合计项数组
            if (excelHeader != null) {
                excelHeaderArray = excelHeader.split(",");
            } else {
                return null;
            }
            if (total != null) {
                totalArray = total.split(",");
            }
            // 设置请求
            response.setContentType("application/application/vnd.ms-excel");
            response.setHeader("Content-disposition",
                    "attachment;filename=" + URLEncoder.encode(fileName + ".xls", "UTF-8"));
            // 创建一个Workbook,对应一个Excel文件
            HSSFWorkbook wb = new HSSFWorkbook();
            // 设置标题样式
            HSSFCellStyle titleStyle = wb.createCellStyle();
            // 设置单元格边框样式
            titleStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);// 上边框 细边线
            titleStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);// 下边框 细边线
            titleStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);// 左边框 细边线
            titleStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);// 右边框 细边线
            // 设置单元格对齐方式
            titleStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 水平居中
            titleStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 垂直居中
            // 设置字体样式
            Font titleFont = wb.createFont();
            titleFont.setFontHeightInPoints((short) 15); // 字体高度
            titleFont.setFontName("黑体"); // 字体样式
            titleStyle.setFont(titleFont);
            // 在Workbook中添加一个sheet,对应Excel文件中的sheet
            HSSFSheet sheet = wb.createSheet(fileName);
            // 标题数组
            String[] titleArray = new String[excelHeaderArray.length];
            // 字段名数组
            String[] fieldArray = new String[excelHeaderArray.length];
            for (int i = 0; i < excelHeaderArray.length; i++) {
                String[] tempArray = excelHeaderArray[i].split("#");// 临时数组 分割#
                titleArray[i] = tempArray[0];
                fieldArray[i] = tempArray[1];
            }
            // 在sheet中添加标题行
            HSSFRow row = sheet.createRow((int) 0);// 行数从0开始
            HSSFCell sequenceCell = row.createCell(0);// cell列 从0开始 第一列添加序号
            sequenceCell.setCellValue("序号");
            sequenceCell.setCellStyle(titleStyle);
            sheet.autoSizeColumn(0);// 自动设置宽度
            // 为标题行赋值
            for (int i = 0; i < titleArray.length; i++) {
                HSSFCell titleCell = row.createCell(i + 1);// 0号位被序号占用,所以需+1
                titleCell.setCellValue(titleArray[i]);
                titleCell.setCellStyle(titleStyle);
                sheet.autoSizeColumn(i + 1);// 0号位被序号占用,所以需+1
            }
            // 数据样式 因为标题和数据样式不同 需要分开设置 不然会覆盖
            HSSFCellStyle dataStyle = wb.createCellStyle();
            // 设置数据边框
            dataStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            dataStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
            dataStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
            dataStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
            // 设置居中样式
            dataStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 水平居中
            dataStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 垂直居中
            // 设置数据字体
            Font dataFont = wb.createFont();
            dataFont.setFontHeightInPoints((short) 12); // 字体高度
            dataFont.setFontName("宋体"); // 字体
            dataStyle.setFont(dataFont);
            // 遍历集合数据,产生数据行
            Iterator<T> it = dataList.iterator();
            int index = 0;
            while (it.hasNext()) {
                index++;// 0号位被占用 所以+1
                row = sheet.createRow(index);
                // 为序号赋值
                HSSFCell sequenceCellValue = row.createCell(0);// 序号值永远是第0列
                sequenceCellValue.setCellValue(index);
                sequenceCellValue.setCellStyle(dataStyle);
                sheet.autoSizeColumn(0);
                T t = (T) it.next();
                // 利用反射,根据传过来的字段名数组,动态调用对应的getXxx()方法得到属性值
                for (int i = 0; i < fieldArray.length; i++) {
                    HSSFCell dataCell = row.createCell(i + 1);
                    dataCell.setCellStyle(dataStyle);
                    String fieldName = fieldArray[i];
                    String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);// 取得对应getXxx()方法
                    Class<? extends Object> tCls = t.getClass();// 泛型为Object以及所有Object的子类
                    Method getMethod = tCls.getMethod(getMethodName, new Class[] {});// 通过方法名得到对应的方法
                    Object value = getMethod.invoke(t, new Object[] {});// 动态调用方,得到属性值
                    if (value != null) {
                        dataCell.setCellValue(value.toString());// 为当前列赋值
                    }
                    sheet.autoSizeColumn(i + 1);
                }
            }
            // 合计项
            if (totalArray != null) {
                row = sheet.createRow(index + 1);
                HSSFCell totalCell = row.createCell(0);// 序号值永远是第0列
                totalCell.setCellValue("合计");
                totalCell.setCellStyle(titleStyle);
                sheet.autoSizeColumn(0);
                for (int i = 0; i < fieldArray.length; i++) {
                    double sum = 0;
                    for (int j = 0; j < totalArray.length; j++) {
                        Iterator<T> iterator = dataList.iterator();
                        if (fieldArray[i].equals(totalArray[j])) {
                            String fieldName = fieldArray[i];
                            String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);// 取得对应getXxx()方法
                            while (iterator.hasNext()) {
                                T t = (T) iterator.next();
                                Class<? extends Object> tCls = t.getClass();// 泛型为Object以及所有Object的子类
                                Method getMethod = tCls.getMethod(getMethodName, new Class[] {});// 通过方法名得到对应的方法
                                Object value = getMethod.invoke(t, new Object[] {});// 动态调用方,得到属性值
                                if (value != null && !"".equals(value)) {
                                    sum += Double.parseDouble(value.toString());
                                }
                            }
                            break;
                        }
                    }
                    HSSFCell totalCellValue = row.createCell(i + 1);
                    totalCellValue.setCellStyle(titleStyle);
                    String val = "";
                    if (sum != 0) {
                        val = RxUtil.getNumber_ROUND_HALF_UP(String.valueOf(sum), 2);
                    }
                    totalCellValue.setCellValue(val);// 为当前列赋值
                    sheet.autoSizeColumn(i + 1);
                }
            }
            OutputStream outputStream = response.getOutputStream();// 打开流
            wb.write(outputStream);// HSSFWorkbook写入流
            wb.close();// HSSFWorkbook关闭
            outputStream.flush();// 刷新流
            outputStream.close();// 关闭流
            return wb;
        }
        // XSSFCellStyle.ALIGN_CENTER 居中对齐
        // XSSFCellStyle.ALIGN_LEFT 左对齐
        // XSSFCellStyle.ALIGN_RIGHT 右对齐
        // XSSFCellStyle.VERTICAL_TOP 上对齐
        // XSSFCellStyle.VERTICAL_CENTER 中对齐
        // XSSFCellStyle.VERTICAL_BOTTOM 下对齐
    
        // CellStyle.BORDER_DOUBLE 双边线
        // CellStyle.BORDER_THIN 细边线
        // CellStyle.BORDER_MEDIUM 中等边线
        // CellStyle.BORDER_DASHED 虚线边线
        // CellStyle.BORDER_HAIR 小圆点虚线边线
        // CellStyle.BORDER_THICK 粗边线
    }
    
    • SQL查询数据库注释
    SELECT
            COLUMN_NAME field,
            column_comment note
            FROM
            INFORMATION_SCHEMA. COLUMNS
            WHERE
            table_name = #{tableName}
            AND
            table_schema = 'boss'
    

    注:COLUMN_NAME为字段名,需要和javabean保持一致,column_comment为注释。注释用”#”分割,有”#”说明可提供导出选择,”#”前面为excel表头名字,后面为注释,可不写。如需合计,在最后加上”,”。
    这里写图片描述
    有”#”的会显示在可选择导出项,有”,”的会显示在可选择合计项。

    • TableInfoServiceImpl.java,用来查询数据库表的字段名与注释
    package com.rixin.common.service;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    
    import javax.annotation.Resource;
    
    import org.springframework.stereotype.Service;
    
    import com.rixin.common.dao.ITableInfoDao;
    import com.rixin.common.model.TableInfo;
    
    @Service("TableInfoServiceImpl")
    public class TableInfoServiceImpl implements ITableInfoService {
        @Resource
        private ITableInfoDao tableInfoDao;
    
        @Override
        public Map<String, Object> geTableInfoList(String tableName) {
            Map<String, Object> result = new HashMap<String, Object>();
            List<TableInfo> exportsList = tableInfoDao.getTableInfo(tableName);// 需要导出列表
            List<TableInfo> totalsList = new ArrayList<TableInfo>();// 需要合计列表
            Iterator<TableInfo> it = exportsList.iterator();// 迭代
            while (it.hasNext()) {
                TableInfo tableInfo = (TableInfo) it.next();
                String note = tableInfo.getNote();// 注释
                int index = note.indexOf("#");// '#'位置
                // '#'存在,需要导出
                if (index > 0) {
                    tableInfo.setNote(note.substring(0, index));//截取注释
                    int totalIndex = note.indexOf(",");
                    // ','存在,需要合计
                    if (totalIndex > 0) {
                        totalsList.add(tableInfo);// 添加到合计列表
                    }
                } else {
                    it.remove();// 不需要导出,移除
                }
    
            }
            result.put("exportsList", exportsList);
            result.put("totalsList", totalsList);
            return result;
        }
    
    }
    
    • 需要导出的表格只需要写个controller即可
    /**
         * 导出Excel
         * 
         * @return
         * @throws IOException
         */
        @RequestMapping("/exportExpenses.do")
        public void exportExpenses(String export, String total, HttpServletResponse response, HttpSession session) {
            Expenses expenses = new Expenses();
            User sessionUser = (User) session.getAttribute("sessionUser");
            // 查找数据
            expenses.setCurrentUserId(sessionUser.getId());
            expenses.setCurrentUserName(sessionUser.getUsername());
            expenses.setCurrentUserDeptId(sessionUser.getDeptId());
            expenses.setCurrentUserDeptName(sessionUser.getDeptName());
            expenses.setCurrentUserDeptWholeId(sessionUser.getDeptWholeId());
            List<Expenses> expensesList = expensesService.getExpensesList(expenses);
            try {
                ExportExcelUtil.export(response, "项目费用支出登记表", export, expensesList, total);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    • JSP需调用
    <button class="am-btn am-btn-primary am-btn-sm"
            <c:if test="${empty expensesList}">disabled="disabled"</c:if>
        onclick="window.open('${basePath}tableInfo/getTableInfo.do?tableName=expenses')">
        <span class="am-icon-bar-chart"></span>&nbsp;导出
    </button>
    • 通用显示导出export_select.jsp
    <div class="am-container" style="background-color: #FFFFFF">
            <div data-am-widget="titlebar" class="am-titlebar am-titlebar-default">
                <h2 class="am-titlebar-title ">选择导出项</h2>
                <nav class="am-titlebar-nav"></nav>
            </div>
            <form class="am-form" method="post"
                action="${basePath}${address}?state=${param.state}">
                <div class="am-g">
                    <c:forEach items="${exportsList }" var="til">
                        <div style="margin-top: 5px;" class="am-u-sm-2">
                            <label class="am-checkbox"> <input type="checkbox"
                                value="${til.note }#${til.field }" name="export" data-am-ucheck
                                checked>${til.note }
                            </label>
                        </div>
                    </c:forEach>
                    <div align="center" class="am-u-sm-12 am-u-md-12"
                        style="margin-top: 0px; margin-bottom: 0px;"></div>
                </div>
                <div data-am-widget="titlebar"
                    class="am-titlebar am-titlebar-default">
                    <h2 class="am-titlebar-title ">选择合计项</h2>
                    <nav class="am-titlebar-nav"></nav>
                </div>
                <c:forEach items="${totalsList }" var="tl">
                    <div style="margin-top: 5px;" class="am-u-sm-2">
                        <label class="am-checkbox"> <input type="checkbox"
                            value="${tl.field }" name="total" data-am-ucheck checked>${tl.note }
                        </label>
                    </div>
                </c:forEach>
                <c:if test="${empty  totalsList}">
                    <div style="margin-top: 15px;" class="am-u-sm-12" align="center">
                        <p>暂无可选择合计项!</p>
                    </div>
                </c:if>
                <div align="center" class="am-u-sm-12 am-u-md-12"
                    style="margin-top: 20px; margin-bottom: 20px;">
                    <c:if test="${viewstate ne 'read'}">
                        <button type="submit" id="subform" name="subform"
                            class="am-btn am-btn-primary" style="width: 100%">导出</button>
                    </c:if>
                </div>
            </form>
        </div>
    • 效果图
      这里写图片描述

    • 结束语
      整个模块大概就是这样,需要导出哪个模块,只需要在页面上调用查找表信息的controller并传递过去表名,然后写一个controller来调用ExportExcelUtil.java即可。同时记得维护数据库注释。因为数据量多,所以想出这么一个方法,日后更改可导出项以及数据库字段名,只需维护数据库注释就可以了,这只是我个人的一点小思路,如果有更好的方法,欢迎讨论~
    展开全文
  • 思路: 做法是从数据库读取表格中的数据,然后通过POI组件将其组装成Excel文件,然后Flex通过navigateToURL()方式获取服务器请求地址,组装数据供服务器端使用。就这么简单,但实现起来还是略微有点儿小麻烦。...

    思路: 做法是从数据库中读取表格中的数据,然后通过POI组件将其组装成Excel文件,然后Flex通过navigateToURL()方式获取服务器请求地址,并组装数据供服务器端使用。就这么简单,但实现起来还是略微有点儿小麻烦。下面我详细介绍整个流程。

    1.环境准备:

         1.1添加POI组件依赖

       

    <dependency>
    			<groupId>org.apache.poi</groupId>
    			<artifactId>poi</artifactId>
    			<version>3.9</version>
    		</dependency>
       

     1.2 安装Flex Builder 4.6

        默认安装即可(略),以插件形式安装至eclipse。


    2.JAVA端组装数据

        以下是业务方面的代码,不同的系统使用的框架略有不同。我这里使用的是spring 3.0 + springmvc+hibernate组合。代码如下所示:

    2.1 Controller层代码

    @RequestMapping(params ="action=exportExcel", method = {RequestMethod.GET, RequestMethod.POST, RequestMethod.HEAD})
        public void excel(HttpServletRequest request, HttpServletResponse response)  throws Exception{
    		 String filename = "节点控制器.xls";	 
    		 String isTemplate = request.getParameter("isTemplate");
    		 int isTemplateNum = Integer.parseInt(isTemplate);
    		 
    		 String concentUID = request.getParameter("concentUID");
    		 String groupMaintainId = request.getParameter("groupMaintainId");
    
    		 String titleLabel = "节点控制器";
    		 HttpWebUtil.responseExportExcelConfig(response, filename);
    		 
    		try{
    			String[] titles = {"编号(必填)", "UID(必填)" , "名称(必填)" , "类型(必填)(1:单灯,2:双灯)",  "经度(可不填)", "纬度(可不填)", "地理位置描述(可不填)", "备注(可不填)"};
    			List<NodeDevice> nodeDeviceList;
    			if(("0").equals(groupMaintainId)){
    				nodeDeviceList = nodeDeviceService.findAllNodeDeviceByConcentUid(concentUID);
    				titleLabel += "(" + "所属集中器'" + concentUID + "')";
    			}else{
    				Long groupId = Long.parseLong(groupMaintainId);
    			   nodeDeviceList = nodeDeviceService.findAllNodeDeviceByGroupMaintainId(groupId);
    			   GroupMaintainEntity entity = groupMaintainService.get(GroupMaintainEntity.class, groupId);
    			   titleLabel += "(" + "所属分组'" + entity.getName() + "')";
    			}
    			Object[][] nodeDevice_datas = {{}};
    			if(nodeDeviceList != null && isTemplateNum != 1){
    				 nodeDevice_datas = new Object[nodeDeviceList.size()][];
    				//包装数据
    				for (int i = 0 ; i < nodeDeviceList.size(); i++){
    					NodeDevice nodeDevice = nodeDeviceList.get(i);
    					Object [] itemObject = {nodeDevice.getId(), nodeDevice.getUid(), nodeDevice.getName(),
    							  nodeDevice.getType(),  nodeDevice.getLatitude(),nodeDevice.getLatitude(),
    							  nodeDevice.getLocationDesc(), nodeDevice.getRemark()
    					}; 
    					nodeDevice_datas[i] = itemObject;
    				}
    		    }
    			  //导出数据至Excel表格中
    			  ExcelFileAssembly.getInstance().assembleData("节点控制器数据", response, titleLabel, titles, nodeDevice_datas);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    2.2 Excel操作类(职责:组装数据,设定样式等)

     POI学习地址: http://poi.apache.org/spreadsheet/quick-guide.html,如下所示:

       

    /**
     * Excel操作类(职责:组装数据,设定样式等)
     * @author xuzhongming
     * 2013-08-22
     */
    public class ExcelFileAssembly {
    	
      /** 使用单例模式 **/
      public static ExcelFileAssembly excelFileAssembly = new ExcelFileAssembly();
      
      public static ExcelFileAssembly getInstance(){
    	  if(excelFileAssembly == null){
    		  excelFileAssembly = new ExcelFileAssembly();
    	  }
    	  return excelFileAssembly;
      }
    	
     /**
     * 组装数据至excel文件中
     * @param sheetLabel
     * @param response
     * @param title
     * @param titles
     * @param sample_data
     * @throws Exception
     */
      public  void assembleData(String sheetLabel, HttpServletResponse response,
    		  					String title, String[] titles, Object[][] sample_data) throws Exception {
          Workbook wb = new HSSFWorkbook();
         // else wb = new XSSFWorkbook();
    
          Map<String, CellStyle> styles = createStyles(wb);
    
          Sheet sheet = wb.createSheet(sheetLabel);
          PrintSetup printSetup = sheet.getPrintSetup();
          printSetup.setLandscape(true);
          sheet.setFitToPage(true);
          sheet.setHorizontallyCenter(true);
          sheet.setDefaultColumnWidth(20);
    
          //title row
          Row titleRow = sheet.createRow(0);
          titleRow.setHeightInPoints(45);
          Cell titleCell = titleRow.createCell(0);
          titleCell.setCellValue(title);
          titleCell.setCellStyle(styles.get("title"));
          
          //设置标题宽度
          sheet.addMergedRegion(CellRangeAddress.valueOf("$A$1:$I$1"));
    
          //设置列
          Row headerRow = sheet.createRow(1);
          headerRow.setHeightInPoints(40);
          Cell headerCell;
          for (int i = 0; i < titles.length; i++) {
              headerCell = headerRow.createCell(i);
              headerCell.setCellValue(titles[i]);
              headerCell.setCellStyle(styles.get("header"));
              
          }
    
          int rownum = 2;
          for (int i = 0; i < 10; i++) {
              Row row = sheet.createRow(rownum++);
              for (int j = 0; j < titles.length; j++) {
                  Cell cell = row.createCell(j);
              }
          }
    
          //设置数据
          for (int i = 0; i < sample_data.length; i++) {
              Row row = sheet.getRow(2 + i);
              for (int j = 0; j < sample_data[i].length; j++) {
                  if(sample_data[i][j] == null) continue;
    
                  if(sample_data[i][j] instanceof String) {
                      row.getCell(j).setCellValue((String)sample_data[i][j]);
                  } else if(sample_data[i][j] instanceof Double){
                      row.getCell(j).setCellValue((Double)sample_data[i][j]);
                  }else if(sample_data[i][j] instanceof Long){
                      row.getCell(j).setCellValue((Long)sample_data[i][j]);
                  }
              }
          }
    
          //设置行宽
          //finally set column widths, the width is measured in units of 1/256th of a character width
          for (int i = 0; i < 9; i++) {
              sheet.setColumnWidth(i, 15 * 256);  //15 characters wide
          }
    
          // Write the output to a file
    //      if(wb instanceof XSSFWorkbook) filename += "x";
         // FileOutputStream out = new FileOutputStream("tt.xls");
         // wb.write(out);
          wb.write(response.getOutputStream());
      }
    
      /**
       * Create a library of cell styles
       */
      private static Map<String, CellStyle> createStyles(Workbook wb){
          Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
          CellStyle style;
          Font titleFont = wb.createFont();
          titleFont.setFontHeightInPoints((short)18);
          titleFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
          style = wb.createCellStyle();
          style.setAlignment(CellStyle.ALIGN_CENTER);
          style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
          style.setFont(titleFont);
          styles.put("title", style);
    
          Font monthFont = wb.createFont();
          monthFont.setFontHeightInPoints((short)11);
          monthFont.setColor(IndexedColors.WHITE.getIndex());
          style = wb.createCellStyle();
          style.setAlignment(CellStyle.ALIGN_CENTER);
          style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
          style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
          style.setFillPattern(CellStyle.SOLID_FOREGROUND);
          style.setFont(monthFont);
          style.setWrapText(true);
          styles.put("header", style);
    
          style = wb.createCellStyle();
          style.setAlignment(CellStyle.ALIGN_CENTER);
          style.setWrapText(true);
          style.setBorderRight(CellStyle.BORDER_THIN);
          style.setRightBorderColor(IndexedColors.BLACK.getIndex());
          style.setBorderLeft(CellStyle.BORDER_THIN);
          style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
          style.setBorderTop(CellStyle.BORDER_THIN);
          style.setTopBorderColor(IndexedColors.BLACK.getIndex());
          style.setBorderBottom(CellStyle.BORDER_THIN);
          style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
          style.setFillForegroundColor(IndexedColors.ORANGE.getIndex());
          style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
          styles.put("cell", style);
    
          return styles;
      }
    }

    3.Flex端访问该请求,并获取下载地址

    	/**
    			 * 动态获取服务器地址,并组装集中器下载地址
    			 **/
    			public function getFileAddress(areaId:int, concentUID:String, groupMaintainId:int, isTemplate:int):String{
    				var _loc_1:* =ExternalInterface.call("function getURL(){return window.location.href;}");
    				var _loc_2:* = _loc_1.split(":");
    				var serverIP:String = _loc_2[1].toString().substring(2);
    				
    				//根据集中器或分组情况导出其数据
    				var url:String="http://"+serverIP+":8080/sems/nodeCtrlDataImport.do?action=exportExcel&areaId=" +
    					areaId + "&concentUID=" + concentUID + "&groupMaintainId=" + 
    					groupMaintainId  + "&isTemplate=" + isTemplate;
    				return url;
    			}
    			
    			/**
    			 * 模板下载
    			 **/ 
    			protected function templeateButton_clickHandler(event:MouseEvent):void
    			{
    				//DownFileUtil.getInstance().downFile('节点控制器数据导入模板.xls');
    				var url:String = getFileAddress(areaSelecter.selectedItem.id, concSelecter.selectedItem.label, groupSelecter.selectedItem.id, 1);
    				var u:URLRequest = new URLRequest(url);
    				
    				u.method = URLRequestMethod.POST;
    				navigateToURL(u,"_blank")
    			}
    			
    			/**
    			 * 数据导出
    			 **/ 
    			protected function exportButton_clickHandler(event:MouseEvent):void
    			{
    			    var url:String = getFileAddress(areaSelecter.selectedItem.id, concSelecter.selectedItem.label, groupSelecter.selectedItem.id, 0);
    				var urlRequest:URLRequest = new URLRequest(url);
    				
    				urlRequest.method = URLRequestMethod.POST;
    				navigateToURL(urlRequest,"_blank");
    			}

    4.效果如下所示:


    表格如下:


    展开全文
  • 导出就有导入,在要向数据库中插入大量的数据时,我们向程序提供准备好的 Excel,然后程序读取表格内容,将数据添加到数据库中。 实现这个「导入/导出 Excel」的功能也不复杂,我们使用第三方的类库即可实现。 1...

    在管理一个系统时,总会有许多的数据,为了方便浏览查看数据,系统总会提供「导出Excel」的功能;有导出就有导入,在要向数据库中插入大量的数据时,我们向程序提供准备好的 Excel,然后程序读取表格内容,并将数据添加到数据库中。

    实现这个「导入/导出 Excel」的功能也不复杂,我们使用第三方的类库即可实现。

    1.技术选型

    能够实现「导入/导出 Excel」的第三方常用类库有 Apache poi、Java Excel(JXL)和阿里巴巴开源的 Easyexcel 等。这么多类库该怎么选呢?在这里我给大家推荐阿里巴巴开源的「Easyexcel」。

    • 性能对比
      poi 和 jxl 对内存的消耗很大,在处理大批量的数据时,容易造成内存溢出。比如处理一个 3M 的 Excel,poi 和 jxl 可能需要上百兆的内存,但 easyexcel 可能只需要几百或几千 KB(内存消耗对比有些夸张)。在性能这一块,Excel 完全是吊打 poi 和 jxl。

    • 学习复杂度对比
      poi,在学习它的时候,理解起来不难,就是操作的时候太特么的难了。因为 poi 需要自己处理数据,还有复杂的表格样式,就光是处理数据这一款就很头疼了。等你写好所有的代码,没有几百行,你是实现不了的。反观 easyexcel。它能自己处理数据,表格格式也简单,即使是小白也很容易上手。在学习复杂的这块也吊打 poi,而 jxl 我没了解,但多半也是被吊打。

    2.easyexc拟解决的问题

    • Excel读写时内存溢出
    • 使用简单
    • Excel格式解析

    3.工作原理

    在这里插入图片描述

    添加maven依赖

    	<!-- EasyExcel核心文件 -->
    	<dependency>
              <groupId>com.alibaba</groupId>
              <artifactId>easyexcel</artifactId>
              <version>2.2.3</version>
         </dependency>
         
         <!-- fastjson依赖包 -->
         <dependency>
              <groupId>com.alibaba</groupId>
              <artifactId>fastjson</artifactId>
              <version>1.2.51</version>
         </dependency>
         
    	<!-- 解析上传数据 -->
    	<dependency>
          <groupId>commons-fileupload</groupId>
          <artifactId>commons-fileupload</artifactId>
          <version>1.4</version>
        </dependency>
    	
    	<!-- slf4j/log4j日志 -->
        <dependency>
          <groupId>log4j</groupId>
          <artifactId>log4j</artifactId>
          <version>1.2.17</version>
        </dependency>
        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-simple</artifactId>
          <version>1.7.25</version>
        </dependency>
    

    Excel下载

    • HTML
    <a href="tAccount/DownLoadExcel">下载</a>
    
    • 封装数据的Java类
    public class User {
    	@ExcelProperty("用户编号")
    	private Integer userId;
    	@ExcelProperty("用户名称")
    	private String userName;
    	@ExcelProperty("用户性别")
    	private String gender;
    	@ExcelProperty("创建时间")
    	private Date createTime;
    }
    
    • 下载操作
    @GetMapping("DownLoadExcel")
        public void dopost(HttpServletRequest request, HttpServletResponse response) throws IOException {
            /**
             * EasyExcel下载步骤
             */
            //设置响应头
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            //设置防止文件名中文乱码
            String fileName = URLEncoder.encode("user1中文文件名","utf-8");
            response.setHeader("Content-disposition", "attachment;filename="+ fileName + ".xlsx");
            //构建写入到Excel中的数据(此数据可以从数据库中获取)
            List<User> users = new ArrayList<>();
            User user1 = new User(1001, "李四1", "男", new Date());
            User user2 = new User(1002, "李四2", "男", new Date());
            User user3 = new User(1003, "李四3", "男", new Date());
            users.add(user1);
            users.add(user2);
            users.add(user3);
            EasyExcel.write(response.getOutputStream(),User.class).sheet("用户信息").doWrite(users);
        }
    

    Excel上传

    • 前端页面
    <form action="tAccount/UploadExcelServlet" method="post" enctype="multipart/form-data">
        <input type="file" name="file">
        <input type="submit" value="上传">
    </form>
    
    • 接收从Excel中获取到的数据
    public class User {
    
    	@ExcelProperty("用户编号")
    	private Integer userId;
    	@ExcelProperty("用户名称")
    	private String userName;
    	@ExcelProperty("用户性别")
    	private String gender;
    	@ExcelProperty("创建时间")
    	private Date createTime;
    }
    
    • 上传操作
     @PostMapping("UploadExcelServlet")
        public void doposts(HttpServletRequest req, HttpServletResponse resp)throws IOException{
            DiskFileItemFactory factory = new DiskFileItemFactory();
            ServletFileUpload fileUpload = new ServletFileUpload(factory);
            //设置单个文件为3M
            fileUpload.setFileSizeMax(1024*1024*3);
            //总文件大小为30M
            fileUpload.setSizeMax(1024*1024*3*10);
    
            try {
                List<FileItem> list = fileUpload.parseRequest(req);
    
                for (FileItem fileItem : list) {
    
                    //判断是否为附件
                    if(!fileItem.isFormField()) {
                        //是附件
                        InputStream inputStream = fileItem.getInputStream();
                        EasyExcel.read(inputStream,User.class,new AnalysisEventListener<User>() {
    
                            @Override
                            public void doAfterAllAnalysed(AnalysisContext arg0) {
                                System.out.println("Excel全部读完被执行......");
                            }
    
                            @Override
                            public void invoke(User data, AnalysisContext arg1) {
                                //读完一行就执行一次(调用数据库进行插入操作)
                                System.out.println("解析一行: "+data);
                            }
                        }).sheet().doRead();
                    }else {
                        //普通表单
                    }
                }
            } catch (FileUploadException e) {
                e.printStackTrace();
            }
            //上传完成进行转发或者重定向
        }
    
    展开全文
  • CSV是逗号分隔文件(Comma Separated Values)的首字母英文缩写,是一种用来存储数据的纯文本格式,通常用于电子表格数据库软件。在 CSV文件中,数据“栏”以逗号分隔,可允许程序通过读取文件为数据重新创建正确的...
  • CSV是逗号分隔文件(Comma Separated Values)的首字母英文缩写,是一种用来存储数据的纯文本格式,通常用于电子表格数据库软件。在 CSV文件中,数据“栏”以逗号分隔,可允许程序通过读取文件为数据重新创建正确的...
  • 获取差异数据并导出Excel总结 前言 在本次项目中,有一个需求,导入本地Excel文件,对比数据库差异数据,再将差异数据导出Excel 项目使用前后端分离,所有这里采用前后端分离思想 一、思路 读取本地Excel文件,...
  • Java利用POI导入excel表格并将数据存到数据库的问题当有合并表情况下,认为左上角单元格据,意思就是 标题 认为是a1,但是当你循环遍历这样的合并表格的话,数据是会重复的,即把合并的单元格拆分...
  • Java CSV xls 操作(导出和导入)

    千次阅读 2019-01-06 15:08:55
    CSV是逗号分隔文件(Comma Separated Values)的首字母英文缩写,是一种用来存储数据的纯文本格式,通常用于电子表格数据库软件。在 CSV文件中,数据“栏”以逗号分隔,可允许程序通过读取文件为数据重新创建正确的...
  • CSV是逗号分隔文件(Comma Separated Values)的首字母英文缩写,是一种用来存储数据的纯文本格式,通常用于电子表格数据库软件。在 CSV文件中,数据“栏”以逗号分隔,可允许程序通过读取文件为数据重新创建正确的...
  • JAVA操作csv文件(导入导出

    千次阅读 2015-11-10 09:50:51
    CSV是逗号分隔文件(Comma Separated Values)的首字母英文缩写,是一种用来存储数据的纯文本格式,通常用于电子表格数据库软件。在 CSV文件中,数据“栏”以逗号分隔,可允许程序通过读取文件为数据重新创建正确的...
  • CSV是逗号分隔文件(Comma Separated Values)的首字母英文缩写,是一种用来存储数据的纯文本格式,通常用于电子表格数据库软件。在 CSV文件中,数据“栏”以逗号分隔,可允许程序通过读取文件为数据重新创建正确的...
  • java开源包1

    千次下载 热门讨论 2013-06-28 09:14:34
    WARTS是一个纯Java数据库工具,可以执行字符编码识别的数据同步。开发它是用于在UTF-8 Oracle实例中使用ASCII编码的Oracle 数据库中来正确的传输非ASCII字符。 Java模板语言 Beetl Beetl,是Bee Template Language的...
  • java开源包12

    热门讨论 2013-06-28 10:14:45
    WARTS是一个纯Java数据库工具,可以执行字符编码识别的数据同步。开发它是用于在UTF-8 Oracle实例中使用ASCII编码的Oracle 数据库中来正确的传输非ASCII字符。 Java模板语言 Beetl Beetl,是Bee Template Language的...
  • Java资源包01

    2016-08-31 09:16:25
    WARTS是一个纯Java数据库工具,可以执行字符编码识别的数据同步。开发它是用于在UTF-8 Oracle实例中使用ASCII编码的Oracle 数据库中来正确的传输非ASCII字符。 Java模板语言 Beetl Beetl,是Bee Template Language的...
  • java开源包101

    2016-07-13 10:11:08
    WARTS是一个纯Java数据库工具,可以执行字符编码识别的数据同步。开发它是用于在UTF-8 Oracle实例中使用ASCII编码的Oracle 数据库中来正确的传输非ASCII字符。 Java模板语言 Beetl Beetl,是Bee Template Language的...
  • java开源包11

    热门讨论 2013-06-28 10:10:38
    WARTS是一个纯Java数据库工具,可以执行字符编码识别的数据同步。开发它是用于在UTF-8 Oracle实例中使用ASCII编码的Oracle 数据库中来正确的传输非ASCII字符。 Java模板语言 Beetl Beetl,是Bee Template Language的...
  • java开源包2

    热门讨论 2013-06-28 09:17:39
    WARTS是一个纯Java数据库工具,可以执行字符编码识别的数据同步。开发它是用于在UTF-8 Oracle实例中使用ASCII编码的Oracle 数据库中来正确的传输非ASCII字符。 Java模板语言 Beetl Beetl,是Bee Template Language的...

空空如也

空空如也

1 2 3 4
收藏数 71
精华内容 28
关键字:

java读取数据库并导出表格

java 订阅