How to Create a CSV and Download Programmatically by Magento 2?

Create Export and Download CSV, Excel or Text File Programmatically in Magento 2 by FileFactory Class.

\Magento\Framework\App\Response\Http\FileFactory used to create CSV and download CSV by Magento way. create() function in FileFactory.php is used for create CSV file.

There are many other ways to download CSV files using Core PHP script but its not the best way to use within the Magento Coding standard.
You can write CSV and download a CSV file using just simple below code snippet in your controller file,

<?php
namespace Rbj\CSV\Controller\Adminhtml\Index;

use Magento\Framework\App\Filesystem\DirectoryList;

class Export extends \Magento\Backend\App\Action
{
    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Framework\App\Response\Http\FileFactory $fileFactory,
        \Magento\Framework\Filesystem $filesystem
    ) {
        $this->_fileFactory = $fileFactory;
        $this->directory = $filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
        parent::__construct($context);
    }

    public function execute()
    {
        $name = date('m_d_Y_H_i_s');
        $filepath = 'export/custom' . $name . '.csv';
        $this->directory->create('export');
        /* Open file */
        $stream = $this->directory->openFile($filepath, 'w+');
        $stream->lock();
        $columns = $this->getColumnHeader();
        foreach ($columns as $column) {
            $header[] = $column;
        }
        /* Write Header */
        $stream->writeCsv($header);

        $products[] = array(1,'Test 1','test 1',100);
        $products[] = array(2,'Test 2','test 2',299);

        foreach ($products as $item) {
            $itemData = [];
            $itemData[] = $item[0];
            $itemData[] = $item[1];
            $itemData[] = $item[2];
            $itemData[] = $item[3];
            $stream->writeCsv($itemData);
        }

        $content = [];
        $content['type'] = 'filename'; // must keep filename
        $content['value'] = $filepath;
        $content['rm'] = '1'; //remove csv from var folder

        $csvfilename = 'Product.csv';
        return $this->_fileFactory->create($csvfilename, $content, DirectoryList::VAR_DIR);
        
    }

    /* Header Columns */
    public function getColumnHeader() {
        $headers = ['Id','Product name','SKU','Price'];
        return $headers;
    }
}

When you run controller action you can download CSV file using just Magento straight forward way.
Using the above way you can download CSV file using Magento 2 Way.

How to convert shipping address into html format using magento 2?

In Magento 2 we can convert Shipping address or billing address into Html format using below code snippet. Sometimes we need to display entire shipping address into CSV column or any specific page at that time below html format will be useful.

You are familiar with How to Get Customer Default billing and shipping address   You can also use shipping/billing address from above way.

For Example, We have just get order shipping address, First load order by order id and after getting order id we have fetch order shipping address.
Call below construct in your php file,

<?php
class MassExport {
    public function __construct(
        \Magento\Sales\Api\OrderRepositoryInterface $orderRepository,
        \Magento\Customer\Model\Address\Config $addressConfig
    ) {
        $this->orderRepository = $orderRepository;
        $this->_addressConfig = $addressConfig;
    }

    /**
     * Render an address as HTML and return the result
     *
     * @return string
     */
    public function _getAddressHtml($orderId)
    {
        try {
            $order = $this->orderRepository->get($orderId);
        } catch (NoSuchEntityException $e) {
            throw new \Magento\Framework\Exception\LocalizedException(__('This order no longer exists.'));
        }
        $address = $order->getShippingAddress();
        $renderer = $this->_addressConfig->getFormatByCode('html')->getRenderer();
        return $renderer->renderArray($address);
    }
}

You need to get address renderer using \Magento\Customer\Model\Address\Config class.
pass html format code and you will get html formatted address.

Call from template file,

    $orderId = 10;
    $shippingAddress = $this->_getAddressHtml($orderId);
    $shippingFormat = strip_tags($this->_getAddressHtml($shippingAddress));
    echo $shippingFormat;

The result will be,

Veronica Costello
6146 Honey Bluff Parkway
Calder,  Michigan, 49628-7978
United States
T:(555) 229-3326

Magento 2 – How to get multiselect option in system configuration using system.xml.

Using below demo we can get multiselect option using system.xml.
For Example, We will get all Customer group of a system and display all the customer group by system.xml in System -> Configuration Section of admin.
Create system.xml file,
Path,   app/code/<Vendorname>/<Modulename>/etc/adminhtml/system.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <section id="catalog">
            <group id="customer_group" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                <field id="list" translate="label" type="multiselect" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="0">
                    <label>Customer Groups</label>
                    <source_model>Vendorname\Modulename\Model\Adminhtml\System\Config\Source\Customer\Group</source_model>
                    <can_be_empty>1</can_be_empty>
                </field>
            </group>
        </section>
    </system>
</config>

You need to get the collection of all customer group using a Model file. Create Model file in your module. You can define your model php file using source_model tag in system.xml file.

Create Group.php file,
Path, app/code/<Vendorname>/<Modulename>/Model/Adminhtml/System/Config/Source/Customer/Group.php

<?php
namespace Vendorname\Modulename\Model\Adminhtml\System\Config\Source\Customer;

class Group implements \Magento\Framework\Option\ArrayInterface
{
    public function __construct(\Magento\Customer\Model\ResourceModel\Group\CollectionFactory $groupCollectionFactory)
    {
        $this->_groupCollectionFactory = $groupCollectionFactory;
    }

    /**
     * @return array
     */
    public function toOptionArray()
    {
        if (!$this->_options) {
            $this->_options = $this->_groupCollectionFactory->create()->loadData()->toOptionArray();
        }
        return $this->_options;
    }
}

Clear Cache using php bin/magento cache:flush

Now You can get the list of customer group in your section with multi-select option.
If you want to get the list of all selected option in PHP file,

<?php
namespace Vendorname\Modulename\Helper;

class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
    public function __construct(
        \Magento\Framework\App\Helper\Context $context
    ) {
        $this->scopeConfig = $context->getScopeConfig();
        parent::__construct($context);
    }
    /**
     * Get Customer group selected list
     */
    public function getCustomerGroupList() {
        $list = $this->scopeConfig->getValue("catalog/customer_group/list",
                \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
        return $list !== null ? explode(',', $list) : [];
    }

Using the above way you can list of all customer group selected in a Configuration section. The result will be a value of all selected customer group with comma separated.