java 导出CSV格式文件 EXCEL打开 防止乱码
Posted JLCUI
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 导出CSV格式文件 EXCEL打开 防止乱码相关的知识,希望对你有一定的参考价值。
package net.joystart.excelTask; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.Resource; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.SftpException; import jxl.Workbook; import jxl.format.Alignment; import jxl.format.Colour; import jxl.format.UnderlineStyle; import jxl.format.VerticalAlignment; import jxl.write.Label; import jxl.write.WritableCellFeatures; import jxl.write.WritableCellFormat; import jxl.write.WritableFont; import jxl.write.WritableSheet; import jxl.write.WritableWorkbook; import jxl.write.WriteException; import jxl.write.biff.RowsExceededException; import net.joystart.common.util.ConfigUtil; import net.joystart.common.util.SftpUtil; import net.joystart.common.util.ZipUtil; import net.joystart.customer.entity.Customer; import net.joystart.customer.service.ICustomerService; import net.joystart.excelTask.entity.CownExcel; import net.joystart.order.entity.Order; import net.joystart.order.service.IOrderService; import net.joystart.vehicle.controller.VehicleController; import net.joystart.vehicle.entity.Parkinglot; import net.joystart.vehicle.entity.Vehicle; import net.joystart.vehicle.service.IParkinglotService; import net.joystart.vehicle.service.IVehicleService; @Component("ExcelController") public class ExcelController { @Resource private ICustomerService customerService; @Resource private IParkinglotService parkinglotService; @Resource IVehicleService vehicleService; @Resource IOrderService orderService; /** * 订单自动服务 */ public void customerExcel() { Map<String, Object> params = new HashMap<String, Object>(); List<Customer> customerList = customerService.list(params); exportExcel("会员信息.xls", customerList); } /** */ /** * 导出数据为XLS格式 * * @param fileName * 文件的名称,可以设为绝对路径,也可以设为相对路径 * @param content * 数据的内容 */ private void exportExcel(String fileName, List<Customer> customers) { WritableWorkbook wwb; FileOutputStream fos; try { String savePath = ConfigUtil.pro.get("excelPath").toString(); Date date = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); String newDate = dateFormat.format(date); File f = new File(savePath); f = new File(f, newDate + ".xls"); // f.createNewFile(); fos = new FileOutputStream(f); wwb = Workbook.createWorkbook(fos); WritableSheet ws = wwb.createSheet("会员列表", 0); // 创建一个工作表 // 设置单元格的文字格式 WritableFont wf = new WritableFont(WritableFont.ARIAL, 12, WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.BLACK); WritableCellFormat wcf = new WritableCellFormat(wf); wcf.setVerticalAlignment(VerticalAlignment.CENTRE); wcf.setAlignment(Alignment.CENTRE); ws.setRowView(1, 500); jxl.write.NumberFormat nf = new jxl.write.NumberFormat("#,##0.00"); // 设置数字格式 jxl.write.WritableCellFormat wcfN = new jxl.write.WritableCellFormat(nf); // 设置格式 // 设置标题行 int rowsCount = customers.size(); // 填充数据的内容 Customer customer; for (int i = 0; i < rowsCount; i++) { customer = customers.get(i); WritableCellFeatures x; ws.addCell(new Label(0, i + 0, customer.getName(), wcf)); ws.addCell(new Label(1, i + 0, customer.getMobile(), wcf)); double orderCost = customer.getRemainmoney() == null ? 0.00 : customer.getRemainmoney().doubleValue(); jxl.write.Number labelOrderCost = new jxl.write.Number(2, i + 1, orderCost, wcfN); // 格式化数值 ws.addCell(labelOrderCost); } wwb.write(); wwb.close(); Date dt = new Date();// 如果不需要格式,可直接用dt,dt就是当前系统时间 DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");// 设置显示格式 String nowTime = ""; nowTime = df.format(dt);// 用DateFormat的format()方法在dt中获取并以yyyy/MM/dd fileName = "用户信息" + nowTime + ".xls"; // 保存EXCEL内容 CownExcel ce = new CownExcel(); ce.setDownloaddate(new Date()); ce.setUrl(f.getPath()); ce.setFileName(newDate + ".xls"); customerService.insertSelective(ce); } catch (IOException e) { } catch (RowsExceededException e) { } catch (WriteException e) { } } public SftpUtil getSFTPChannel() { return new SftpUtil(); } // 导出运管需要的数据 public void exportTransportationExcel() { try { String savePath = ConfigUtil.pro.get("excelPath").toString(); Date date = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); String newDate = dateFormat.format(date); String str = "北京巴歌汽车租赁有限公司,001615,北京,北京市"; byte[] data = str.getBytes("utf-8"); String url = new StringBuffer(savePath).append("/COL_DEP_").append(newDate).append("_").append(data.length) .append(".csv").toString(); fileOutupload(data, url); /// 添加压缩功能///////////////////////////////////////////////////////////////////// String zipName = new StringBuffer().append("/COL_DEP_").append(newDate).append(".zip").toString(); String zipUrl = new StringBuffer(savePath).append(zipName).toString(); ZipUtil zip = new ZipUtil(); zip.zip(zipUrl, url); File csvFile = new File(url); File zipFile = new File(zipUrl); if (csvFile.exists()) csvFile.delete();// 删除旧压缩包 byte[] file = fileInupload(zipUrl); String zipNameNew = new StringBuffer(savePath).append("/COL_DEP_").append(newDate).append("_") .append(file.length).append(".zip").toString(); fileOutupload(file, zipNameNew); zipFile.delete(); // 调用sftp开始上传文件////////////////////////////////////////////////////////////// VehicleController vehicleController = new VehicleController(); SftpUtil channel = vehicleController.getSFTPChannel(); ChannelSftp chSftp = channel.getChannel(60000); String strSaveUrl = new StringBuffer("/COLLECTION/").append(zipNameNew).toString(); chSftp.put(zipNameNew, strSaveUrl, ChannelSftp.OVERWRITE); chSftp.quit(); channel.closeChannel(); } catch (JSchException e) { e.printStackTrace(); } catch (SftpException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } ExcelMethod1(); ExcelMethod2(); ExcelMethod3(); ExcelMethod4(); ExcelMethod5(); } private void ExcelMethod1(){ FileOutputStream out=null; OutputStreamWriter osw=null; BufferedWriter bw=null; String urlNew=""; String savePath = ConfigUtil.pro.get("excelPath").toString(); Date date = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); String newDate = dateFormat.format(date); String url = new StringBuffer(savePath).append("/COL_DEP_").append(newDate).append(".csv").toString(); File csvFile = new File(url); try { out = new FileOutputStream(csvFile); osw = new OutputStreamWriter(out,"UTF-8");
//识别UTF-8 加上就能识别出来,不加还是乱码 add cjl
osw.write(new String(new byte[] { (byte) 0xEF, (byte) 0xBB,(byte) 0xBF })); osw.write(new String(new byte[] { (byte) 0xEF, (byte) 0xBB,(byte) 0xBF })); bw =new BufferedWriter(osw); List<Parkinglot> parklotList = parkinglotService.findAllParkingLotAndBranch(); if(parklotList!=null && !parklotList.isEmpty()){ for(Parkinglot parking : parklotList){ String strData = new StringBuffer().append(parking.getName()).append(",").append("北京巴歌汽车租赁有限公司").append(","). append(parking.getLongitude()).append(",").append(parking.getLatitude()).append(",").append("null").append(",").append(parking.getPosition()) .append(",").append("null").append(",").append("null").toString(); bw.append(strData).append("\r"); } } } catch (Exception e) { e.printStackTrace(); }finally{ if(bw!=null){ try { bw.close(); bw=null; } catch (IOException e) { e.printStackTrace(); } } if(osw!=null){ try { osw.close(); osw=null; } catch (IOException e) { e.printStackTrace(); } } if(out!=null){ try { out.close(); out=null; } catch (IOException e) { e.printStackTrace(); } } long fileSize = csvFile.length(); urlNew = new StringBuffer(savePath).append("/COL_DEP_").append(newDate).append("_").append(fileSize).append(".csv").toString(); fileupload(url,urlNew); csvFile.delete(); } zipUpload(newDate,savePath,urlNew,"/COL_DEP_"); } private void ExcelMethod2() { FileOutputStream out=null; OutputStreamWriter osw=null; BufferedWriter bw=null; String urlNew=""; String savePath = ConfigUtil.pro.get("excelPath").toString(); Date date = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String newDate = dateFormat.format(date); String url = new StringBuffer(savePath).append("/COL_CAR_").append(newDate).append(".csv").toString(); File csvFile = new File(url); try { out = new FileOutputStream(csvFile); osw = new OutputStreamWriter(out,"UTF-8"); osw.write(new String(new byte[] { (byte) 0xEF, (byte) 0xBB,(byte) 0xBF })); bw =new BufferedWriter(osw); /// 租赁门店信息//////////////////////////////////////////////////////////////// List<Vehicle> vehicleList = vehicleService.selectAllVehicle(); if(vehicleList!=null && !vehicleList.isEmpty()){ for(Vehicle vehicle : vehicleList){ String strData = new StringBuffer().append(vehicle.getPlatenumber()).append(",").append(vehicle.getEngineno()).append(","). append(vehicle.getVin()).append(",").append(vehicle.getUploadImgUrl()).append(",").append(vehicle.getUploadImgUrlTwo()).append(",").append(vehicle.getCarcolor()) .append(",").append(vehicle.getDrivinglicenseurl()).append(",").append("null").append(",") .append("null").append(",").append("5").append(",").append("null").append(",").append(vehicle.getCreatedate() == null ? "" : sdf.format(vehicle.getCreatedate())).append(",") .append("null").append(",").append("null").toString(); bw.append(strData).append("\r"); } } } catch (Exception e) { e.printStackTrace(); }finally{ if(bw!=null){ try { bw.close(); bw=null; } catch (IOException e) { e.printStackTrace(); } } if(osw!=null){ try { osw.close(); osw=null; } catch (IOException e) { e.printStackTrace(); } } if(out!=null){ try { out.close(); out=null; } catch (IOException e) { e.printStackTrace(); } } long fileSize = csvFile.length(); urlNew = new StringBuffer(savePath).append("/COL_CAR_").append(newDate).append("_").append(fileSize).append(".csv").toString(); fileupload(url,urlNew); csvFile.delete(); } zipUpload(newDate,savePath,urlNew,"/COL_CAR_"); } private void ExcelMethod3() { FileOutputStream out=null; OutputStreamWriter osw=null; BufferedWriter bw=null; String urlNew=""; String savePath = ConfigUtil.pro.get("excelPath").toString(); Date date = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); String newDate = dateFormat.format(date); String url = new StringBuffer(savePath).append("/COL_ASS_").append(newDate).append(".csv").toString(); File csvFile = new File(url); try { out = new FileOutputStream(csvFile); osw = new OutputStreamWriter(out,"UTF-8"); osw.write(new String(new byte[] { (byte) 0xEF, (byte) 0xBB,(byte) 0xBF })); bw =new BufferedWriter(osw); List<Vehicle> vehicleList = vehicleService.selectAllVehicleSite(); if(vehicleList!=null && !vehicleList.isEmpty()){ for(Vehicle vehicle : vehicleList){ String strData = new StringBuffer().append(vehicle.getPlatenumber()).append(",").append("null").append( StringUtils.isBlank(vehicle.getUploadImgUrlTwo())? vehicle.getUploadImgUrl() : vehicle.getUploadImgUrlTwo()) .append(",").append(vehicle.getDrivinglicenseurl()).toString(); bw.append(strData).append("\r"); } } } catch (Exception e) { e.printStackTrace(); }finally{ if(bw!=null){ try { bw.close(); bw=null; } catch (IOException e) { e.printStackTrace(); } } if(osw!=null){ try { osw.close(); osw=null; } catch (IOException e) { e.printStackTrace(); } } if(out!=null){ try { out.close(); out=null; } catch (IOException e) { e.printStackTrace(); } } long fileSize = csvFile.length(); urlNew = new StringBuffer(savePath).append("/COL_CAR_").append(newDate).append("_").append(fileSize).append(".csv").toString(); fileupload(url,urlNew); csvFile.delete(); } zipUpload(newDate,savePath,urlNew,"/COL_CAR_"); } private void ExcelMethod4() { FileOutputStream out=null; OutputStreamWriter osw=null; BufferedWriter bw=null; String urlNew=""; String savePath = ConfigUtil.pro.get("excelPath").toString(); Date date = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String newDate = dateFormat.format(date); String url = new StringBuffer(savePath).append("/COL_CON_").append(newDate).append(".csv").toString(); File csvFile = new File(url); try { out = new FileOutputStream(csvFile); osw = new OutputStreamWriter(out,"UTF-8"); osw.write(new String(new byte[] { (byte) 0xEF, (byte) 0xBB,(byte) 0xBF })); bw =new BufferedWriter(osw); Map<String, Object> params = new HashMap<String, Object>(); Calendar calendar_as = Calendar.getInstance(); calendar_as.setTime(new Date()); Calendar calendar_ST = Calendar.getInstance(); calendar_ST.set(calendar_as.get(Calendar.YEAR), calendar_as.get(Calendar.MONTH), calendar_as.get(Calendar.DATE) - 1, 0, 0, 0); calendar_ST.set(Calendar.MILLISECOND, 0); Calendar calendar_ET = Calendar.getInstance(); calendar_ET.set(calendar_as.get(Calendar.YEAR), calendar_as.get(Calendar.MONTH), calendar_as.get(Calendar.DATE), 0, 0, 0); calendar_ET.set(Calendar.MILLISECOND, 0); SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd"); params.put("_startDate", dft.format(calendar_ST.getTime())); params.put("_endDate", dft.format(calendar_ET.getTime())); List<Order> orderList = orderService.selectAllOrders(params); if(orderList!=null && !orderList.isEmpty()){ for(Order order : orderList){ String strData = new StringBuffer().append(order.getOrderno()).append(",").append(order.getPlatenumber()).append(",") .append("null,null,null,null,null,").append(order.getCreatedate() == null ? " " : sdf.format(order.getCreatedate())) .append(",").append(order.getReturnvehicledate() == null ? " " : sdf.format(order.getReturnvehicledate())) .append(",").append(StringUtils.isBlank(order.getRentBranchName()) ? order.getRentParkName() : order.getRentBranchName()).append(",").append("null").append(order.getCreatedate() == null ? "" : sdf.format(order.getCreatedate())) .append(",").append(order.getCustomerName()).append(",").append(order.getInvitationCode()) .append(",null,null,null").toString(); bw.append(strData).append("\r"); } } } catch (Exception e) { e.printStackTrace(); }finally{ if(bw!=null){ try { bw.close(); bw=null; } catch (IOException e) { e.printStackTrace(); } } if(osw!=null){ try { osw.close(); osw=null; } catch (IOException e) { e.printStackTrace(); } } if(out!=null){ try { out.close(); out=null; } catch (IOException e) { e.printStackTrace(); } } long fileSize = csvFile.length(); urlNew = new StringBuffer(savePath).append("/COL_CON_").append(newDate).append("_").append(fileSize).append(".csv").toString(); fileupload(url,urlNew); csvFile.delete(); } zipUpload(newDate,savePath,urlNew,"/COL_CON_"); } private void ExcelMethod5() { FileOutputStream out=null; OutputStreamWriter osw=null; BufferedWriter bw=null; String urlNew=""; String savePath = ConfigUtil.pro.get("excelPath").toString(); Date date = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String newDate = dateFormat.format(date); String url = new StringBuffer(savePath).append("/COL_WAY_").append(newDate).append(".csv").toString(); File csvFile = new File(url); try { out = new FileOutputStream(csvFile); osw = new OutputStreamWriter(out,"UTF-8"); //识别UTF-8 加上就能识别出来,不加还是乱码 add cjl osw.write(new String(new byte[] { (byte) 0xEF, (byte) 0xBB,(byte) 0xBF })); bw =new BufferedWriter(osw); Map<String, Object> params = new HashMap<String, Object>(); Calendar calendar_as = Calendar.getInstance(); calendar_as.setTime(new Date()); Calendar calendar_ST = Calendar.getInstance(); calendar_ST.set(calendar_as.get(Calendar.YEAR), calendar_as.get(Calendar.MONTH), calendar_as.get(Calendar.DATE) - 1, 0, 0, 0); calendar_ST.set(Calendar.MILLISECOND, 0); Calendar calendar_ET = Calendar.getInstance(); calendar_ET.set(calendar_as.get(Calendar.YEAR), calendar_as.get(Calendar.MONTH), calendar_as.get(Calendar.DATE), 0, 0, 0); calendar_ET.set(Calendar.MILLISECOND, 0); SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd"); params.put("_startDate", dft.format(calendar_ST.getTime())); params.put("_endDate", dft.format(calendar_ET.getTime())); List<Order> orderList = orderService.selectAllOrders(params); if(orderList!=null && !orderList.isEmpty()){ for(Order order : orderList){ String strData = new StringBuffer().append(order.getOrderno()).append(",").append(order.getOrderno()).append(",") .append("null,null,null,null,null,").append(order.getCreatedate() == null ? " " : sdf.format(order.getCreatedate())) .append(order.getPlatenumber()).append(",null,null,null,null,null,").append(order.getChargingstartdate() == null ? "" : sdf.format(order.getChargingstartdate())) .append(",").append(order.getReturnvehicledate() == null ? " " : sdf.format(order.getReturnvehicledate())) .append(",").append("null").append(",").append("null").append(",").append(order.getMileage()== null ? "0" : order.getMileage().toString()) .append(",").append(order.getActualpaymentcost() == null ? "0" : order.getActualpaymentcost().toString()).toString(); bw.append(strData).append("\r"); } } } catch (Exception e) { e.printStackTrace(); }finally{ if(bw!=null){ try { bw.close(); bw=null; } catch (IOException e) { e.printStackTrace(); } } if(osw!=null){ try { osw.close(); osw=null; } catch (IOException e) { e.printStackTrace(); } } if(out!=null){ try { out.close(); out=null; } catch (IOException e) { e.printStackTrace(); } } long fileSize = csvFile.length(); urlNew = new StringBuffer(savePath).append("/COL_WAY_").append(newDate).append("_").append(fileSize).append(".csv").toString(); fileupload(url,urlNew); csvFile.delete(); } zipUpload(newDate,savePath,urlNew,"/COL_WAY_"); } /** * 获取文件大小 重新写入磁盘 * * @author:cuijinlong * @date:2017年5月18日 下午1:58:37 * @param url1 * @param url2 */ private void fileOutupload(byte[] b, String url2) { FileOutputStream out = null; try { File f2 = new File(url2);//新文件路径 add 崔金龙 out = new FileOutputStream(f2);//输出文件 out.write(b);//写入文件内容 旧文件内容 写入新的里面去 add 崔金龙 out.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (out != null) { out.close(); } } catch (IOException e) { e.printStackTrace(); } } } /** * 根据路径读取旧文件路径下内容,写入新文件路径下 * @author:cuijinlong * @date:2017年5月19日 上午11:26:31 * @param url1 * @param url2 */ private void fileupload(String url1, String url2) { File f = new File(url1); InputStream in = null; FileOutputStream out = null; try { in = new FileInputStream(f);//输入流读出就文件内容 add 崔金龙 int tempbyte; System.out.println(in.available()); byte[] b = new byte[in.available()]; //读出内容 获取大小 add 崔金龙 while ((tempbyte = in.read(b, 0, b.length)) != -1) { System.out.write(tempbyte); } File f2 = new File(url2);//新文件 out = new FileOutputStream(f2);//输出新文件 out.write(b);//把旧路径内容写入新地址文件去 add 崔金龙 out.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (in != null) { in.close(); } if (out != null) { out.close(); } } catch (IOException e) { e.printStackTrace(); } } } /** * 根据URL路径获取当面文件大小 * @author:cuijinlong * @date:2017年5月19日 上午11:18:59 * @param url1 * @return */ private byte[] fileInupload(String url1) { File f = new File(url1);//根据URL路径获取文件信息 InputStream in = null; try { in = new FileInputStream(f); int tempbyte; System.out.println(in.available()); byte[] b = new byte[in.available()];//读出文件里面内容并获取文件大小 注释:b:为内容 b.length() 获取文件大小 add 崔金龙 while ((tempbyte = in.read(b, 0, b.length)) != -1) { System.out.write(tempbyte); } return b; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (in != null) { in.close(); } } catch (IOException e) { e.printStackTrace(); } } return null; } /** * 上传压缩包文件变并且替换 * @author:cuijinlong * @date:2017年5月19日 上午10:35:34 * @param newDate * @param savePath//上传文件路径 * @param urlNew//新的上传文件地址加上CSV文件名称 * @param flag */ private void zipUpload(String newDate,String savePath,String urlNew,String flag){ try { //拼接压缩包名称 add cjl String zipName = new StringBuffer().append(flag).append(newDate).append(".zip").toString(); String zipUrl = new StringBuffer(savePath).append(zipName).toString(); ZipUtil zip = new ZipUtil(); zip.zip(zipUrl, urlNew); File zipFile = new File(zipUrl);//生成压缩包路径带上压缩包名称 add 崔金龙 File csvFileNew = new File(urlNew);//为了删除CSV文件时候建立的FILE为了删除使用,如果不删除不需要使用 if(csvFileNew.exists()) csvFileNew.delete(); byte[] file = fileInupload(zipUrl);//获取该路径下文件大小,注意此处一定带着要获取文件的文件名称 add 崔金龙 String zipNameNew = new StringBuffer(savePath).append(flag).append(newDate).append("_") .append(file.length).append(".zip").toString();//file.length 可以获取文件大小,生成一个新的路径带着文件大小的 add 崔金龙 fileOutupload(file, zipNameNew);//把旧压缩包内容 写入新的压缩包里面去 add 崔金龙 zipFile.delete(); // 调用sftp开始上传文件////////////////////////////////////////////////////////////// VehicleController vehicleController = new VehicleController(); SftpUtil channel = vehicleController.getSFTPChannel(); ChannelSftp chSftp = channel.getChannel(60000); String strSaveUrl = new StringBuffer("/COLLECTION/").append(zipNameNew).toString(); chSftp.put(zipNameNew, strSaveUrl, ChannelSftp.OVERWRITE); chSftp.quit(); channel.closeChannel(); } catch (Exception e) { e.printStackTrace(); } } }
以上是关于java 导出CSV格式文件 EXCEL打开 防止乱码的主要内容,如果未能解决你的问题,请参考以下文章