jjzjj

EasyExcel导入

qq_47614329 2023-11-06 原文

方式一:
Controller层

 @PostMapping("/import")
    public Result<String> importDemo(HttpServletRequest request, @RequestParam("file") MultipartFile file) {
        log.info("import.request:{}", file.getOriginalFilename());
        if (file.getOriginalFilename() == null || !file.getOriginalFilename().endsWith("xlsx")) {
            throw new Exception("只支持.xlsx类型的文件导入!");
        }
        // 读取Excel内容
        List<DemoPo> demoList;
        try {
            ExcelImportPoSoAdapter adapter = new ExcelImportPoSoAdapter();
            EasyExcelFactory.read(file.getInputStream(), DemoPo.class, adapter).doReadAll();
            Map<String, String> map = adapter.getMap();
            if (map.size() != 0){
                throw  new BizException(map.get("msg"));
            }
            demoList= adapter.demoList();
        } catch (Exception e) {
            log.error("import.error:", e);
            throw new Exception("您上传的文件格式与模板格式不一致,请检查后重新上传");
        }
        if(demoList.size() > 500){
            throw new Exception("Excel数据超出限制, 最大支持导入500条!");
        }
        if (ObjectUtil.isEmpty(demoList)) {
            throw new Exception("导入数据为空,请添加数据后再次导入");
        }
        demoUserCase.save(request, demoList);
        log.info("import:success");
        return Result.buildResult(null);
    }

Excel适配器类

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
/**
 * Excel适配器
 */
@Slf4j
@Getter
public class ExcelImportPoSoAdapter extends AnalysisEventListener<ExcelPayload> {
    
    /**
     * 数据集合
     */
    List<DemoPo> demoPoList = new ArrayList<>();
 
    // 此map用来存储错误提示
    protected Map<String, String> map = new HashMap<>();
 
     /**
     * 校验表头
     */
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        // headMap.containsKey(下标),先判空
        // headMap.get(0).equals() 判内容是否相符
        if (!headMap.containsKey(0) || !headMap.containsKey(1)
                || !headMap.get(0).equals("enmu1") || !headMap.get(1).equals("enmu2")) {
            // 这里给demoPoList 加1条空数据,是因为doAfterAllAnalysed方法最后有判是否是空列表
            demoPoList.add(new DemoPo());
            map.put("msg", "您上传的文件格式与模板格式不一致,请检查后重新上传");
        }
    }
    @Override
    public void invoke(ExcelPayload excelPayload, AnalysisContext analysisContext) {
        demoPoList .add(excelPayload.excelPayloadToDemoPo(excelPayload));
    }
 
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        log.info("ExcelImportAdapter.doAfterAllAnalysed.success");
    }
}

service
接着写业务的逻辑校验

执行批量导入

注:注意List切片,因为sql传入参数最大限制2100个

import com.google.common.collect.Lists;
上方为该Lists导包
List<List<DemoPo>> partition = Lists.partition(demoList, 100);

方式二:
1.项目依赖
demo项目基于springboot2.2.1版本。

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
        <relativePath/>
    </parent>

    <groupId>com.evan.easyexcel</groupId>
    <artifactId>easyexcel-basic-demo</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>easyexcel-basic-demo</name>
    <description>Easy excel 2.x import and export demo</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>4.1.0</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.1.6</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2.ExcelApplication 主启动类

package com.evan.easyexcel;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ExcelApplication {

    public static void main(String[] args) {
        SpringApplication.run(ExcelApplication.class, args);
    }
}

3.定义导入和导出模型

package com.evan.easyexcel.model;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import lombok.Data;

/**
 * @ClassName ExportModel
 * @Description 导出模型
 * @Author Evan Wang
 * @Version 1.0.0
 * @Date 2020/4/1 20:55
 */
@ContentRowHeight(20)
@HeadRowHeight(25)
@ColumnWidth(25)
@Data
public class ExportModel  {

    @ExcelProperty(value = "姓名" ,index = 0)
    private String name;

    @ExcelProperty(value = "性别" ,index = 1)
    private String sex;

    @ExcelProperty(value = "年龄" ,index = 2)
    private Integer age;

}

package com.evan.easyexcel.model;

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

/**
 * @ClassName ImportModel
 * @Description 导入模型
 * @Author Evan Wang
 * @Version 1.0.0
 * @Date 2020/4/1 20:54
 */
@Data
public class ImportModel {

    @ExcelProperty(index = 0)
    private String date;

    @ExcelProperty(index = 1)
    private String author;

    @ExcelProperty(index = 2)
    private String book;

}

4.Object与实体类转换工具类

package com.evan.easyexcel.utils.common;

import org.springframework.beans.BeanUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @ClassName ExportModel
 * @Description Object与实体类转换工具类
 * @Author Evan Wang
 * @Version 1.0.0
 * @Date 2020/4/1 20:59
 */
public class BeanConvert {
    private BeanConvert(){}
    /**
     * 将List<Object> 转换为List<Bean>
     * @param sources 源对象
     * @param targetClass 目标类
     * @param <T>
     * @return
     */
    public static <T> List<T> objectConvertBean(List<?> sources, Class<T> targetClass) {
        List<?> sourcesObj = sources;
        if (sourcesObj == null) {
            sourcesObj = Collections.emptyList();
        }
        List<T> targets = new ArrayList<>(sourcesObj.size());
        convert(sourcesObj, targets, targetClass);
        return targets;
    }

    /**
     * 复制源对象到目的对象
     * 注意:
     *   org.springframework.beans.BeanUtils.copyProperties 是一个Spring提供的名称相同的工具类
     *   但它不支持类型自动转换,如果某个类型属性不同,则不予转换那个属性
     *   org.apache.commons.beanutils.BeanUtils 是一个Apache提供的名称相同的工具类
     *   支持类型自动转换,如Date类型会自动转换为字符串
     * @param sources  源对象
     * @param targets 目的对象
     * @param targetClass 目标类
     * @param <T>
     */
    private static <T> void convert(List<?> sources, List<T> targets, Class<T> targetClass) {
        if (sources == null) {
            return;
        }
        if (targets == null) {
            return;
        }
        targets.clear();
        for (Object obj : sources) {
            try {
                T target = targetClass.newInstance();
                targets.add(target);
                BeanUtils.copyProperties(obj, target);
            } catch (Exception e) {
                return;
            }
        }
    }

}

5.ExcelListener 监听器

package com.evan.easyexcel.utils.excel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.evan.easyexcel.model.ImportModel;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author Evan Wang
 * @Description 监听类
 * @Date 2019-09-16
 */
public class ExcelListener extends AnalysisEventListener {
    //可以通过实例获取该值
    private List<Object> dataList = new ArrayList<>();


    @Override
    public void invoke(Object object, AnalysisContext context) {
        //数据存储到list,供批量处理,或后续自己业务逻辑处理。
        dataList.add(object);
        handleBusinessLogic();

          /*
        如数据过大,可以进行定量分批处理
        if(dataList.size()>=200){
            handleBusinessLogic();
            dataList.clear();
        }
         */
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        //非必要语句,查看导入的数据
        System.out.println("导入的数据 " + dataList.toString());
        //解析结束销毁不用的资源
        dataList.clear();
    }

    //根据业务自行实现该方法,例如将解析好的dataList存储到数据库中
    private void handleBusinessLogic() {

    }

    public List<Object> getDataList() {
        return dataList;
    }

    public void setDataList(List<Object> dataList) {
        this.dataList = dataList;
    }
}

6.ExcelUtil (核心类)
ExcelUtil对easyexcel2.X进行封装,实现一个方法完成简单的excel导入和导出。

package com.evan.easyexcel.utils.excel;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.evan.easyexcel.utils.common.BeanConvert;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @Author Evan Wang
 * @Description Excel读写工具类
 * @Date 2019-09-16
 */
public class ExcelUtil {

    private ExcelUtil(){}

    /**
     * 读取Excel(一个sheet)
     * @param excel 文件
     * @param clazz 实体类
     * @param sheetNo sheet序号
     * @return 返回实体列表(需转换)
     */
    public static <T> List<T> readExcel(MultipartFile excel, Class<T> clazz,int sheetNo) {

        ExcelListener excelListener = new ExcelListener();

        ExcelReader excelReader = getReader(excel,clazz,excelListener);
        if (excelReader == null) {
            return new ArrayList<>();
        }

        ReadSheet readSheet = EasyExcel.readSheet(sheetNo).build();
        excelReader.read(readSheet);
        excelReader.finish();

        return BeanConvert.objectConvertBean(excelListener.getDataList(), clazz);
    }


    /**
     * 读取Excel(多个sheet可以用同一个实体类解析)
     * @param excel 文件
     * @param clazz 实体类
     * @return 返回实体列表(需转换)
     */
    public static <T> List<T> readExcel(MultipartFile excel, Class<T> clazz) {

        ExcelListener excelListener = new ExcelListener();
        ExcelReader excelReader = getReader(excel,clazz,excelListener);

        if (excelReader == null) {
            return new ArrayList<>();
        }

        List<ReadSheet> readSheetList = excelReader.excelExecutor().sheetList();

        for (ReadSheet readSheet:readSheetList){
            excelReader.read(readSheet);
        }
        excelReader.finish();

        return BeanConvert.objectConvertBean(excelListener.getDataList(), clazz);
    }


    /**
     * 导出Excel(一个sheet)
     *
     * @param response  HttpServletResponse
     * @param list      数据list
     * @param fileName  导出的文件名
     * @param sheetName 导入文件的sheet名
     * @param clazz 实体类
     */
    public static <T> void  writeExcel(HttpServletResponse response,List<T> list, String fileName, String sheetName, Class<T> clazz) {

        OutputStream outputStream = getOutputStream(response, fileName);

        ExcelWriter excelWriter = EasyExcel.write(outputStream, clazz).build();
        WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();

        excelWriter.write(list, writeSheet);

        excelWriter.finish();
    }


    /**
     * 导出Excel(带样式)
     *
     * @return
     */
    public static  <T> void writeStyleExcel(HttpServletResponse response,List<T> list, String fileName, String sheetName, Class<T> clazz) {
        //表头策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        //背景浅灰
        headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short)20);
        headWriteCellStyle.setWriteFont(headWriteFont);

        //内容策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        //这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 否则无法显示背景颜色;头默认了FillPatternType
        contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        //背景浅绿
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
        WriteFont contentWriteFont = new WriteFont();
        //字体大小
        contentWriteFont.setFontHeightInPoints((short)15);
        contentWriteCellStyle.setWriteFont(contentWriteFont);

        HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

        OutputStream outputStream = getOutputStream(response, fileName);
        EasyExcel.write(outputStream, clazz).registerWriteHandler(horizontalCellStyleStrategy).sheet(sheetName).doWrite(list);

    }


    /**
     * 导出Excel(动态表头)
     * write时不传入class,table时传入并设置needHead为false
     * @return
     */
    public static  <T> void writeDynamicHeadExcel(HttpServletResponse response,List<T> list, String fileName, String sheetName, Class<T> clazz,List<List<String>> headList) {

        OutputStream outputStream = getOutputStream(response, fileName);

        EasyExcel.write(outputStream)
                .head(headList)
                .sheet(sheetName)
                .table().head(clazz).needHead(Boolean.FALSE)
                .doWrite(list);
    }


    /**
     * 导出时生成OutputStream
     */
    private static OutputStream getOutputStream(HttpServletResponse response,String fileName) {
        //创建本地文件
        String filePath = fileName + ".xlsx";
        File file = new File(filePath);
        try {
            if (!file.exists() || file.isDirectory()) {
                file.createNewFile();
            }
            fileName = new String(filePath.getBytes(), "ISO-8859-1");
            response.addHeader("Content-Disposition", "filename=" + fileName);
            return response.getOutputStream();
        } catch (IOException  e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 返回ExcelReader
     * @param excel         文件
     * @param clazz         实体类
     * @param excelListener
     */
    private static <T> ExcelReader getReader(MultipartFile excel, Class<T> clazz, ExcelListener excelListener) {
        String filename = excel.getOriginalFilename();

        try {
            if (filename == null || (!filename.toLowerCase().endsWith(".xls") && !filename.toLowerCase().endsWith(".xlsx"))) {
                return null;
            }

            InputStream inputStream = new BufferedInputStream(excel.getInputStream());

            ExcelReader excelReader = EasyExcel.read(inputStream, clazz, excelListener).build();

            inputStream.close();

            return excelReader;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

7.ExcelTestController

package com.evan.easyexcel.controller;

import com.evan.easyexcel.model.ExportModel;
import com.evan.easyexcel.model.ImportModel;
import com.evan.easyexcel.utils.excel.ExcelUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName ExcelTestController
 * @Description
 * @Author Evan Wang
 * @Version 1.0.0
 * @Date 2020/4/1 21:25
 */
@RestController
@RequestMapping(value = "/easyExcel")
public class ExcelTestController {

    @PostMapping(value = "/import")
    public List<ImportModel> read(MultipartFile excel) {
        return ExcelUtil.readExcel(excel, ImportModel.class, 0);
    }

    @GetMapping(value = "/export")
    public void writeExcel(HttpServletResponse response) {
        List<ExportModel> list = getList();
        String fileName = "Excel导出测试";
        String sheetName = "sheet1";
        ExcelUtil.writeDynamicHeadExcel(response, list, fileName, sheetName, ExportModel.class, head());
    }

    private List<ExportModel> getList() {
        List<ExportModel> modelList = new ArrayList<>();

        ExportModel firstModel = new ExportModel();
        firstModel.setName("李明");
        firstModel.setSex("男");
        firstModel.setAge(20);
        modelList.add(firstModel);

        ExportModel secondModel = new ExportModel();
        secondModel.setName("珍妮");
        secondModel.setSex("女");
        secondModel.setAge(19);
        modelList.add(secondModel);

        return modelList;
    }

    private List<List<String>> head() {
        List<List<String>> headList = new ArrayList<>();
        List<String> nameHead = new ArrayList<>();
        nameHead.add("姓名");
        List<String> genderHead = new ArrayList<>();
        genderHead.add("性别");
        List<String> ageHead = new ArrayList<>();
        ageHead.add("年龄");
        headList.add(nameHead);
        headList.add(genderHead);
        headList.add(ageHead);

        return headList;
    }
}

8.application.yml 端口号配置

server:
  port: 8090

四、项目测试
1.导出测试
先启动项目,然后在浏览器中访问如下地址。

http://localhost:8090/easyExcel/export


五、总结
到此为止,EasyExcel 2.x版本的代码示范就结束了,需要源码的小伙伴可以访问我的git获取。
虽然上面已经写过了,但是避免粗心的小伙伴看不到,再重复一下。

源码地址:https://github.com/wangming2674/easyexcel-basic-demo

另外,我在应用时,是前后端分离架构,前端用的vue.js。
————————————————
版权声明:本文为CSDN博主「Evan Wang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41378597/article/details/105267953

有关EasyExcel导入的更多相关文章

  1. ruby - 检查是否通过 require 执行或导入了 Ruby 程序 - 2

    如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby​​文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否

  2. Ruby:如何从另一个文件导入变量? - 2

    我正在尝试创建一个与compass一起使用的本地配置文件,这样我们就可以处理开发人员机器上的不同导入路径。到目前为止,我已经尝试将文件导入到异常block中,以防它不存在,然后进一步使用该变量:local_config.rbVENV_FOLDER='venv'config.rbVENV_FOLDER='.'beginrequire'local_config.rb'rescueLoadErrorendputsVENV_FOLDER通常我是一名Python开发人员,所以我希望导入将VENV_FOLDER的值更改为venv,但它仍然是。之后。有没有一种方法可以导入local_config.r

  3. ruby - Ruby 导入的方法总是私有(private)的吗? - 2

    最好用一个例子来解释:文件1.rb:deffooputs123end文件2.rb:classArequire'file1'endA.new.foo将给出错误“':调用了私有(private)方法'foo'”。我可以通过执行A.new.send("foo")来解决这个问题,但是有没有办法公开导入的方法?编辑:澄清一下,我没有混淆include和require。另外,我不能使用正常包含的原因(正如许多人正确指出的那样)是因为这是元编程设置的一部分。我需要允许用户在运行时添加功能;例如,他可以说“run-this-app--includefile1.rb”,应用程序的行为将根据他在file1

  4. ruby-on-rails - Rails 导入 CSV 错误 : invalid byte sequence in UTF-8 - 2

    尝试在我的Rails应用程序中导入CSV文件时,出现错误UTF-8中的无效字节序列。一切正常,直到我添加了一个gsub方法来将其中一个CSV列与我的数据库中的一个字段进行比较。当我导入CSV文件时,我想检查每一行的地址是否包含在特定客户端的不同地址数组中。我有一个带有alt_addresses属性的客户端模型,其中包含客户端地址的几种不同可能格式。然后我有一个引用模型(如果您熟悉本地SEO,您就会知道这个术语)。引用模型没有地址字段,但它有一个nap_correct?字段(NAP代表“姓名”、“地址”、“电话号码”)。如果CSV行的名称、地址和电话号码与我在该客户的数据库中拥有的相同,

  5. ruby - git:从 bitbucket 导出并导入 github(带提交) - 2

    我在bitbucket上创建了一个私有(private)git存储库并提交了代码。现在我想导出所有(提交、代码、历史记录)并将其导入github上的gitrepo。有没有办法做到这一点?谢谢 最佳答案 在本地检查所有内容到您的计算机和gitpull。创建一个github存储库将此存储库添加为您的第二个远程(“使用gitremote添加githubURL”)推送到第二个Remote 关于ruby-git:从bitbucket导出并导入github(带提交),我们在StackOverflow

  6. ruby - 使用 rake 导入(调用其他 rakefile) - 2

    这是我的主要rake文件subrake='subrake'task:init=>[subrake]do#callsubrake.buildendimportsubrake我看到有关上述步骤如何工作的文档,但我无法弄清楚如何调用其他subrake文件中的任务。顺便说一句,这些任务可能与我的同名,这是个问题吗? 最佳答案 我想我回答晚了,但几分钟前我也有同样的问题。因此该解决方案可能对某些人有用。Rakefile.rbsubrake='subrake'task:default=>:inittask:init=>["#{subrake}:

  7. ruby - 使用 Sinatra 时如何从 gem 导入 rake 任务? - 2

    我正在尝试向orientdbgem添加一些基本的rake任务,这将允许我创建数据库、创建数据库迁移和迁移数据库——类似于rails迁移。当我在本地执行rake任务时,我可以使用db:settings、db:create和db:create_migration,但是在将它们放入gem之后,我不知道如何从Sinatra访问它们使用“rake”时的应用。我有一种感觉,我要么是a)没有正确地组织gem中的文件和/或b)没有从Sinatra应用程序正确地调用东西。我的fork存储库的当前状态是https://github.com/ricaurte/orientdb-jruby我将任务文件放在li

  8. ruby-on-rails - 将现有的 Rails 应用程序导入 RubyMine 项目 - 2

    我目前在尝试测试RubyMine时遇到了不必要的麻烦。我最大的问题是我无法找到一种方法将我系统上的现有Rails应用程序转换为官方RubyMine应用程序,以便我可以体验RubyMine的所有功能。我唯一可用的选项是创建一个新的RubyMinerails项目,从git远程拉取一个rails项目(不起作用),或者打开以前的rails目录(它允许您编辑rails代码,但它无法将此目录识别为RubyMine项目,因此我无法充分利用RubyMine对rails的所有好处)。请帮帮我,RubyMine看起来很有前途顺便说一句,这是RubyMine4。 最佳答案

  9. ruby-on-rails - 如何编写 Rake 任务将数据导入 Rails 应用程序? - 2

    目标:使用CRON任务(或其他预定事件)更新数据库,每晚从现有系统导出数据。所有数据都是在现有系统中创建/更新/删除的。该网站不直接与该系统集成,因此Rails应用程序只需要反射(reflect)数据导出中出现的更新。我有一个包含约5,000种产品的.txt文件,如下所示:"1234":"productname":"attr1":"attr2":"ABCManufacturing":"2222""A134":"anotherproduct":"attr1":"attr2":"FoobarWorld":"2447"...所有值都是用双引号(")括起来的字符串,用冒号(:)分隔字段是:id

  10. ruby - 如何将 ruby​​ 类导入主文件? - 2

    我正在尝试学习如何使用Ruby进行编程,我想为单独的类创建单独的文件,但是当我这样做时,我收到以下消息:NameError:uninitializedconstantBookconst_missingatorg/jruby/RubyModule.java:2677(root)at/Users/Friso/Documents/Projects/RubyApplication1/lib/main.rb:1但是,如果我将类直接放入主文件中,它就可以工作。我该如何解决这个问题?主要代码:book1=Book.new("1234","Hello","Ruby")book2=Book.new("4

随机推荐