avro/csv-bundle

Symfony2 CSV Bundle

安装量: 36,695

依赖: 1

建议者: 0

安全性: 0

星标: 29

关注者: 5

分支: 14

公开问题: 4

类型:symfony-bundle

v1.0.1 2021-11-23 02:50 UTC

README

此Bundle提供了一种简单的方法,通过仅配置少量参数,使用CSV文件将数据上传到您的数据库。

状态

此Bundle处于开发阶段,可能会出现错误。

限制

此Bundle使用php和Doctrine2,不是导入巨大型CSV文件的最佳选择。请使用您数据库的本地导入和导出解决方案。

特性

  • 通过CSV文件导入数据
  • 将数据导出到CSV文件
  • 一些用于读取/写入CSV文件的服务

支持

  • Doctrine ORM

安装

此Bundle已列在Packagist上。

只需将其添加到您的应用的composer.json文件中

    "avro/csv-bundle": "^0.4.2"

同时启用config/bundles.php中的Bundle以及相关的AvroCaseBundle

    Avro\CsvBundle\AvroCsvBundle::class => ['all' => true],
    Avro\CaseBundle\AvroCaseBundle::class => ['all' => true],

配置

添加以下必需配置

# config/packages/avro_csv.yaml
avro_csv:
    db_driver: orm # supports orm
    batch_size: 15 # The batch size between flushing & clearing the doctrine object manager
    tmp_upload_dir: "%kernel.root_dir%/../web/uploads/tmp/" # The directory to upload the csv files to
    sample_count: 5 # The number of sample rows to show during mapping

将路由添加到您的配置中

# config/routes/avro_csv.yaml
avro_csv:
    resource: "@AvroCsvBundle/Resources/config/routing.yml"

添加您想要实现导入/导出的实体/文档

# config/packages/avro_csv.yaml
avro_csv:
    # 
    objects: # the entities/documents you want to be able to import/export data with 
        client:
            class: Avro\CrmBundle\Entity\Client # The entity/document class
            redirect_route: avro_crm_client_list # The route to redirect to after import
        invoice:
            class: Avro\CrmBundle\Entity\Invoice
            redirect_route: avro_crm_invoice_list

要排除某些字段映射,请使用ImportExclude注释,如下所示。

namespace Avro\CrmBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Avro\CsvBundle\Annotation\ImportExclude;

/**
 * Avro\CrmBundle\Entity\Client
 *
 * @ORM\Entity
 */
class Client
{
    /**
     * @var string
     *
     * @ORM\Column(type="string", length=100, nullable=true)
     * @ImportExclude
     */
    protected $password;

导入

为任何数量的实体/文档实现导入。您只需将它们添加到前面提到的对象节点中。

然后只需包含一个指向特定导入页面的链接,如下所示

<a href="{{ path('avro_csv_import_upload', {'alias': 'client'}) }}">Go to import page</a>

将"client"替换为您在配置中指定的实体/文档的别名。

视图

此Bundle附带了一些基本的Twitter Bootstrap视图,您可以通过扩展Bundle来覆盖它们。

关联映射

在导入关联字段时,会触发一个事件,以允许实现适合您自己的逻辑。

只需在您的应用中创建一个自定义监听器,以监听AssociationFieldEvent::class事件。

一个简单的实现,通过名称获取关联实体,可能如下所示

namespace App\EventListener;

use Avro\CsvBundle\Event\AssociationFieldEvent;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Csv import listener
 */
class ImportListener implements EventSubscriberInterface
{
    private $em;

    /**
     * @param EntityManagerInterface   $em      The entity manager
     */
    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }
    
    public static function getSubscribedEvents()
    {
        return [
            AssociationFieldEvent::class => 'importAssociation',
        ];
    }

    /**
     * Set the objects createdBy field
     *
     * @param AssociationFieldEvent $event
     */
    public function importAssociation(AssociationFieldEvent $event)
    {
        $association = $event->getAssociationMapping();
        switch ($association['type']) {
            case ClassMetadataInfo::ONE_TO_ONE:
            case ClassMetadataInfo::MANY_TO_ONE:
                $relation = $this->em->getRepository($association['targetEntity'])->findOneBy(
                    [
                        'name' => $event->getRow()[$event->getIndex()],
                    ]
                );
                if ($relation) {
                    $event->getObject()->{'set'.ucfirst($association['fieldName'])}($relation);
                }
                break;
        }
    }
}

自定义每一行

想要自定义每一行上的某些字段?没问题。

当添加行时,会触发一个事件,您可以利用此事件来自定义每行数据。

只需在您的应用中创建一个自定义监听器,以监听RowAddedEvent::class事件。

例如...

namespace App\EventListener;

use Avro\CsvBundle\Event\RowAddedEvent;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\SecurityContextInterface;

/**
 * Csv import listener
 */
class ImportListener implements EventSubscriberInterface
{
    private $em;
    private $context;

    /**
     * @param EntityManagerInterface   $em      The entity manager
     * @param SecurityContextInterface $context The security context
     */
    public function __construct(EntityManagerInterface $em, SecurityContextInterface $context)
    {
        $this->em = $em;
        $this->context = $context;
    }
    
    public static function getSubscribedEvents()
    {
        return [
            RowAddedEvent::class => 'setCreatedBy',
        ];
    }

    /**
     * Set the objects createdBy field
     *
     * @param RowAddedEvent $event
     */
    public function setCreatedBy(RowAddedEvent $event)
    {
        $object = $event->getObject();

        $user = $this->context->getToken()->getUser();

        $object->setCreatedBy($user);
    }
}

注册您的监听器或使用自动装配

导出

此Bundle提供了一些简单的导出功能。

导航到"/export/your-alias"将导出所有数据到CSV,并允许您从浏览器下载。

您可以通过监听相应的事件(请参阅Avro\CsvBundle\Event命名空间中的事件)来自定义导出查询构建器和导出数据。

如果想要自定义返回的数据,只需创建自己的控制器操作,并从导出器中获取queryBuilder,在调用"getContent()"之前添加约束。

例.

namespace App\Controller;

use Avro\CsvBundle\Export\ExporterInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

class ExportController extends AbstractController
{
    /**
     * Export a db table.
     *
     * @param ExporterInterface $exporter The exporter
     * @param string            $alias    The objects alias
     *
     * @return Response
     */
    public function exportAction(ExporterInterface $exporter, string $alias): Response
    {
        $class = $this->getParameter(sprintf('avro_csv.objects.%s.class', $alias));

        $exporter->init($class);

        // customize the query
        $qb = $exporter->getQueryBuilder();
        $qb->where('o.fieldName =? 1')->setParameter(1, false);

        $content = $exporter->getContent();

        $response = new Response($content);
        $response->headers->set('Content-Type', 'application/csv');
        $response->headers->set('Content-Disposition', sprintf('attachment; filename="%s.csv"', $alias));

        return $response;
    }
}

注册您的控制器或使用您已经设置的自动装配

待办事项

  • 完成MongoDB支持

致谢

感谢jwage的EasyCSV为一些基础工作。

反馈和拉取请求非常欢迎!