You should use this plugin   to add snippets. Pro users should set mode “Run snippet everywhere” if they use  scheduled jobs!
You can use textarea “Custom PHP code” in section “Misc Settings” too (except codes from section “Add Fields”! ).

The snippets are grouped by purpose: Add Fields, Sort orders, Filter orders, Format output, Actions after export, Alter summary report, Sample addons, Columns for each currency, Sort by product names, Add products as columns

Use documentation to understood naming for hooks/filters

Modify Existing Fields

// add order prefix
add_filter('woe_get_order_value_order_number','woe_format_order_number', 10, 3);
function woe_format_order_number($value, $order, $fieldname) {
	return "KTR-" . $value;
}
// remove line breaks from customer note 
add_filter('woe_get_order_value_customer_note',function ($value, $order,$fieldname) {
	return preg_replace( "/\r|\n/", "", $value);
},10,3);
// custom Shipping Full Name  ( last + first )
add_filter('woe_get_order_value_shipping_full_name',function ($value, $order,$fieldname) {
	return get_post_meta($order->id,'_shipping_last_name',true) . ' '  . get_post_meta($order->id,'_shipping_first_name',true);
},10,3);
// format product weight, 0.2->0.200  and 0.12->0.120
add_filter('woe_get_order_product_value_weight','woe_format_weight', 10, 4);
function woe_format_weight($value, $order, $item, $product) {
	return number_format($value,3,'.','');
}
// remap shipping method titles
add_filter('woe_get_order_value_shipping_method_title','woe_rename_shipping_method_title', 10, 3);
function woe_rename_shipping_method_title($value, $order, $fieldname) {
 if($value == 'UK Standard Shipping') // copy these 2 lines for other mappings
        return 'STANDARD';            // copy these 2 lines for other mappings
 return $value;
}
// duplicate each item "qty" times! and set qty=1 for the item
add_filter( "woe_fetch_order_products", function ($products, $order, $labels, $format, $static_vals) {
	$new_products = array();
	//need to know counters, as field "qty" can be omitted in output!
	foreach($order->get_items('line_item') as $pos=>$item) {
				if( isset($products[$pos]['qty']) )
						$products[$pos]['qty'] =1;
				for($i=0;$i< $item['qty'];$i++) 
						$new_products[] = $products[$pos];
	} 
	return $new_products;
} , 10, 5);
//convert "order total" and "item price"  from CNY to USD
class WOE_currency_mod {
	var $rate = false;
	
	function __construct() {
		add_filter('woe_get_order_value_order_total',array($this,'convert_cny_usd'), 10, 2);
		add_filter('woe_get_order_product_value_item_price',array($this,'convert_cny_usd'), 10, 2);
	}	
	
	function convert_cny_usd($value, $order) {
		return round( $value * $this->get_rate(), 2 );
	}
	
	function get_rate() {
		if( $this->rate === false) {
			$response = wp_remote_get("http://api.fixer.io/latest?base=CNY&symbols=USD");
			$api_response = json_decode( wp_remote_retrieve_body( $response ), true );
			$this->rate = $api_response['rates']['USD'];
		}
		return $this->rate;
	}
}	
new WOE_currency_mod();

Add New Fields

// add order field "Order Time"
add_filter('woe_get_order_fields', function ($fields) {
	$fields['order_time'] = array( 'label' => 'Order Time', 'colname' => 'Order Time', 'checked' => 1 );
	return $fields;
});
// calculate new field
add_filter('woe_get_order_value_order_time', function ($value,$order, $field) {
	return $order->get_date_created()->date("H:i:s");
}, 10, 3);
// add product field "Quantity x Name"
add_filter('woe_get_order_product_fields', 'add_product_two_fields', 10, 2);
function add_product_two_fields($fields,$format) {
	$fields['qty_name'] = array( 'label' => 'Quantity x Name', 'colname' => 'Quantity x Name', 'checked' => 1 );
	return $fields;
}
add_filter('woe_get_order_product_value_qty_name', 'get_product_addon_qty_name', 10, 4);
function get_product_addon_qty_name($value,$order, $item, $product) {
	return $item['qty'] .' x '. $item['name'];
}
// add field  "orders per customer"
add_filter('woe_get_order_fields', function ($fields) {
	$fields['customer_num_orders'] = array( 'label' => 'Total orders per Customer', 'colname' => 'Total orders per Customer', 'checked' => 1 );
	return $fields;
});
// calculate  new field
add_filter('woe_get_order_value_customer_num_orders', function ($value,$order, $field) {
	$customer_id = $order->user_id;
	return $customer_id ? wc_get_customer_order_count($customer_id) : 0 ;
}, 10, 3);
// add new field "shipping + tax"
add_filter('woe_get_order_fields', 'woe_addd_shipping_plus_tax_field' );
function woe_addd_shipping_plus_tax_field($fields) {
	$fields['order_shipping_plus_tax'] = array('segment'=>'cart','label'=>'Order shipping plus tax','colname'=>'Order shipping plus tax','value'=>'','checked'=>1);
	return $fields;
}
add_filter('woe_get_order_value_order_shipping_plus_tax','woe_fill_order_shipping_plus_tax', 10, 4);
function woe_fill_order_shipping_plus_tax($value, $order, $item, $product) {
	return $order->order_shipping+$order->order_shipping_tax;
}
 // new column "All Fees"
add_filter('woe_get_order_fields', function ($fields) {
	$fields['all_fees'] = array( 'label' => 'All Fees', 'colname' => 'All Fees', 'checked' => 1 );
	return $fields;
});
add_filter('woe_get_order_value_all_fees', function ($value,$order) {
	$result = 0; 	
	foreach($order->get_items('fee') as $fee) {
		$result += $fee['line_total'];
	}
	return $result;
},10, 2);
// add field  "line number",  use button "Export w/o progressbar"
add_filter('woe_get_order_fields',  function ($fields) {
	$fields['line_no'] = array( 'label' => 'Line Number', 'colname' => 'Line Number', 'checked' => 1 );
	return $fields;
});
//enumerate exported rows 
add_filter('woe_fetch_order_data', function ($rows) {
	static $line_no = 1;
	$key = 'line_no';
	$pos = array_search( $key, array_keys($rows[0]), true );
	if( $pos  !== false) {
		foreach($rows as $i=>$row) {
			if( isset($rows[$i][$key]))
				$rows[$i][$key]  = $line_no++;
			else //2nd, 3rd ,4... rows for same order have numeric index
				$rows[$i][$pos]  = $line_no++;
		}
	}
	return $rows;
});
// add field "Date Processed", based on order's comments
add_filter('woe_get_order_fields', 'woe_func_add_order_fields');
function woe_func_add_order_fields($fields) {
    $fields['date_processed'] = array( 'label' => 'Date Processed', 'colname' =>'Date Processed', 'segment' => 'user', 'checked' => 1 );
    return $fields;
}
add_filter('woe_get_order_value_date_processed','woe_get_value_date_processed',10, 2);
function woe_get_value_date_processed($value,$order) {
    $args = array(
		'post_id' 	=> $order->id,
		'approve' 	=> 'approve',
		'type' 		=> 'order_note',
		'search'        => 'Order status changed from Pending Payment to Processing.',
    );
    // woocommerce hides such records by default
    remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10 );
    $notes = get_comments( $args );
    add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 );

    $date_processed = '';
    if(!empty($notes)) {
        $date_processed = date("m/d/Y",strtotime($notes[0]->comment_date)); // to US format
    }
    return $date_processed;
}
//export Shipping line as Products 
add_filter('woe_fetch_order_products','woe_add_shipping_as_products', 10, 5);
function woe_add_shipping_as_products($products,$order,$labels, $format, $static_vals) {
	$i = count ($products);
	foreach ( $order->get_items('shipping') as $item_id=>$item ) {
		$row = array();
		$i++;
		$item["taxes"] = unserialize($item["taxes"]);
		foreach ( $labels as $field => $label ) {
			if ( $field == 'line_id' ) {
				$row[ $field ] = $i;
			} elseif ( $field == 'sku' ) {
				$row[ $field ] = $item["method_id"];
			} elseif ( $field == 'name' ) {
				$row['name'] = $item["name"];
			} elseif ( $field == 'qty' ) {
				$row['qty'] = 1;
			} elseif ( $field == 'item_price' ) {
				$row['item_price'] = $item["cost"] + array_sum($item["taxes"]);
			} elseif ( $field == 'price' ) {
				$row['price'] = $item["cost"]  + array_sum($item["taxes"]);
			} elseif ( isset( $static_vals[ $field ] ) ) {
				$row[ $field ] = $static_vals[ $field ];
			} 
		}
		$products[] = $row;
	}
	return $products;
}
//export Fee line as Products
add_filter('woe_fetch_order_products', function ($products, $order, $labels, $format, $static_vals) {
    $i = count($products);
    foreach($order-> get_items('fee') as $item_id => $item) {
        $item_meta = $order->get_item_meta( $item_id );
        $fee_amount = $item_meta['_fee_amount'][0];
        $tax_amount = $item_meta['_line_tax'][0];
        $row = array();
        $i++;
        foreach($labels as $field => $label) {
            if ($field == 'line_id') {
                $row[$field] = $i;
            }
            elseif($field == 'name') {
                $row['name'] = $item["name"];
            }
            elseif($field == 'qty') {
                $row['qty'] = 1;
            }
            elseif($field == 'tax_rate') {
                $row[$field] = round($tax_amount/$fee_amount*100);
            }
            elseif($field == 'line_no_tax') {
                $row[$field] = $fee_amount;
            }
            elseif($field == 'line_tax') {
                $row[$field] = $tax_amount;
            }
            elseif($field == 'line_subtotal') {
                $row[$field] = $fee_amount;
            }
            elseif($field == 'line_total') {
                $row[$field] = $fee_amount;
            }
            elseif($field == 'line_total_plus_tax') {
                $row[$field] = $fee_amount + $tax_amount;
            }
        }
        $products[] = $row;
    }
    return $products;
}, 10, 5);
//add all taxes as columns
class WOE_add_all_taxes{
	var $taxes;
	
	function __construct() {
		add_filter('woe_get_order_fields', array($this,'add_order_fields'), 10, 1);
		add_filter('woe_order_export_started',array($this,'fetch_order_taxes'), 10, 1);
	}	
	
	function add_order_fields($fields) {
		global $wpdb;
		
		$taxes = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}woocommerce_tax_rates");
		foreach($taxes  as $tax) {
			$fields['tax_'.$tax->tax_rate_id] = array('label'=>$tax->tax_rate_name,'checked' => 1, 'segment'=>'cart','colname'=>$tax->tax_rate_name);
			add_filter('woe_get_order_value_tax_'.$tax->tax_rate_id, array($this,'get_tax_value'), 10, 3);
		}	
		return $fields;
	}

	function fetch_order_taxes($order_id) {
		//reset values
		$this->taxes = array();
		//read taxes
		$order = new WC_Order($order_id);
		foreach($order->get_tax_totals() as $code=>$tax) {
			$this->taxes['tax_'.$tax->rate_id ] =  wc_round_tax_total($tax->amount);
		}
                return $order_id;
	}
	
	function get_tax_value($value, $order,$field) { 
		return isset($this->taxes[$field]) ? $this->taxes[$field] : 0;
	}
}	
new WOE_add_all_taxes();
//add fees as columns
class WOE_add_fees_columns{
	var $order_fees;
	var $fee_columns;
	
	function __construct() {
		add_filter('woe_get_order_fields', array($this,'add_order_fields'), 10, 1);
		add_filter('woe_order_export_started',array($this,'fetch_order_fees'), 10, 1);
	}	
	
	function add_order_fields($fields) {
		global $wpdb;
		$fees = $wpdb->get_results("SELECT DISTINCT order_item_name FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_type='fee' ORDER BY order_item_name");
		foreach($fees as $fee) {
			$key = 'fee_'.md5($fee->order_item_name);
			$fields[ $key ] = array('label'=>$fee->order_item_name,'checked' => 1, 'segment'=>'cart','colname'=>$fee->order_item_name, 'format'=>'money');
			add_filter('woe_get_order_value_'.$key, array($this,'get_fee_value'), 10, 3);
			
			$key = 'fee_tax_'.md5($fee->order_item_name);
			$fields[ $key ] = array('label'=>$fee->order_item_name. " Tax",'checked' => 1, 'segment'=>'cart','colname'=>$fee->order_item_name. " Tax", 'format'=>'money');
			add_filter('woe_get_order_value_'.$key, array($this,'get_fee_value'), 10, 3);
			
			$key = 'fee_plus_tax_'.md5($fee->order_item_name);
			$fields[ $key ] = array('label'=>$fee->order_item_name. " + Tax",'checked' => 1, 'segment'=>'cart','colname'=>$fee->order_item_name. " + Tax", 'format'=>'money');
			add_filter('woe_get_order_value_'.$key, array($this,'get_fee_value'), 10, 3);
		}	
		return $fields;
	}

	function fetch_order_fees($order_id) {
		//reset values
		$this->order_fees = array();
		
		//read fees
		$order = new WC_Order($order_id);
		foreach($order-> get_items('fee') as $item_id => $item) {
			$key = 'fee_'.md5($item['name']);
			$this->order_fees[ $key ] =  $item['total'];
			$key = 'fee_tax_'.md5($item['name']);
			$this->order_fees[ $key ] =  $item['total_tax'];
			$key = 'fee_plus_tax_'.md5($item['name']);
			$this->order_fees[ $key ] =  $item['total']+$item['total_tax'];
		}
		return $order_id;
	}
	
	function get_fee_value($value, $order,$field) { 
		return isset($this->order_fees[$field]) ? $this->order_fees[$field] : 0;
	}
}	
new WOE_add_fees_columns();

Sort orders

// sort products by SKU, inside order
add_filter('woe_fetch_order_products','woe_sort_products_by_sku', 10, 5);
function woe_sort_products_by_sku($products, $order, $labels, $format, $static_vals) {
	usort($products, function($a, $b){
		if ($a['sku'] == $b['sku']) return 0;
		return ($a['sku'] < $b['sku']) ? -1 : 1;
	});
	return $products;
}
// sort by billing full name using SQL filters
add_filter('woe_sql_get_order_ids_left_joins', function ($joins) {
	global $wpdb;
	$joins[] = "LEFT JOIN {$wpdb->postmeta} AS billing_last ON (billing_last.post_id = orders.ID AND billing_last.meta_key='_billing_last_name')";
	$joins[] = "LEFT JOIN {$wpdb->postmeta} AS billing_first ON (billing_first.post_id = orders.ID AND billing_first.meta_key='_billing_first_name')";
	return $joins;
});

add_filter('woe_sql_get_order_ids_fields', function ($fields) {
 	return "ID AS order_id, CONCAT(billing_first.meta_value,billing_last.meta_value) AS billing_name";
});

add_filter('woe_sql_get_order_ids_order_by', function ($order_by) {
	return "ORDER BY billing_name";
});
// sort by usernames using SQL filters
add_filter('woe_sql_get_order_ids_left_joins','woe_join_usernames');
function woe_join_usernames($joins) {
	global $wpdb;
	$joins[] = "LEFT JOIN {$wpdb->postmeta} AS order_usernames ON (order_usernames.post_id = orders.ID AND order_usernames.meta_key='_customer_user')";
	$joins[] = "LEFT JOIN {$wpdb->users} AS users ON users.ID = order_usernames.meta_value";
	//var_dump($joins);	die();
	return $joins;
}
add_filter('woe_sql_get_order_ids_fields','woe_set_select_fields');
function woe_set_select_fields($fields) {
 	return "orders.ID AS order_id,users.user_login AS username";
 }
add_filter('woe_sql_get_order_ids_order_by','woe_sort_orders_by_usernames');
function woe_sort_orders_by_usernames($order_by) {
	return "ORDER BY username";
}

Filter orders

// don't export orders with total < 1
add_filter( 'woe_fetch_order_row', 'woe_filter_orders_by_sum',10,2);
function woe_filter_orders_by_sum( $row,$order_id ) { 
  return ($row['order_total']<1) ? false : $row;
}
// replace {yesterday} and {today}  with actual values in settings, tweak formats for your needs
add_filter('woe_settings_validate_defaults', function ($settings) {
	$settings = json_encode($settings); // to string
	$yesterday = date("Y-m-d" , strtotime("-1 day",  current_time( 'timestamp' ) ));
	$settings = str_replace( '{yesterday}', $yesterday, $settings);
	$today = date("Y-m-d" , current_time( 'timestamp' ) );
	$settings = str_replace( '{today}', $today, $settings);
	$settings = json_decode($settings, true); // to array
	return $settings;
} );

Format output

// CSV without quotes
add_filter('woe_csv_custom_output_func','woe_csv_no_quotes', 10, 6);
function woe_csv_no_quotes($custom_output,$handle,$data,$delimiter,$linebreak,$enclosure) {
	fwrite($handle, join($delimiter, $data)."\r\n" );
	$custom_output = true; //stop fputcsv!
	return $custom_output;
}
// CSV force quotes
add_filter('woe_csv_custom_output_func',function ($custom_output,$handle,$data,$delimiter,$linebreak,$enclosure) {
	foreach($data as $k=>$v) 
		$data[$k] =  $enclosure . str_replace($enclosure, $enclosure . $enclosure, $v) . $enclosure;
	fwrite($handle, join($delimiter, $data). $linebreak  );
	return true;  //stop default fputcsv!
}, 10, 6);
 // format Excel column as number
add_action( 'woe_xls_print_footer', function ($objXls,$formatter) {
 $row = $formatter->last_row;
 $formatter->objPHPExcel->getActiveSheet()->getStyle( "K1:K" . $row)->getNumberFormat()->setFormatCode('0.00');
} ,10, 2); 
// fixed width, you should use format TSV! 
add_filter('woe_tsv_custom_output_func', function ($custom_output,$handle,$data,$delimiter,$linebreak,$enclosure) {
	$default_len = 10;
	$len = array(20,20,20,20,20,20,20,20,20,20); //define  width for each column

	$data = array_values($data);
	foreach( $data as $pos=>$v) {
		$l =  isset($len[$pos]) ?  $len[$pos] : $default_len;
		$v = substr($v, 0, $l);// truncate long values
		$data[$pos] = str_pad($v, $l, " ", STR_PAD_RIGHT); // or STR_PAD_LEFT ? edit it!
	}
	
	fwrite($handle, join("", $data). $linebreak);
	return true; //stop fputcsv!
}, 10, 6);
// merge product rows to one row
add_filter( "woe_fetch_order_products", function( $products, $order, $labels, $format, $static_vals ) {
	$one_product = array();
	foreach($products as $product) {
		foreach($product as $k=>$v) {
		if( isset($one_product[$k]) )
			$one_product[$k] .= "  \n".$v;
		else
			$one_product[$k] = $v;
		}
	}
	return array( $one_product );
},10,5);
//customize json 
class WOE_add_customer_json {
	function __construct() {
		add_filter('woe_fetch_order_row',array($this,'woe_remember_order_id'), 10, 2);
		add_filter('woe_json_output_filter', array($this,'woe_add_json_customer'), 10, 2);
	}	

	function woe_remember_order_id($row,$order_id) {
		$this->order_id = $order_id;
		return $row;
	}

	function woe_add_json_customer($json,$data) {
		$order = new WC_Order($this->order_id);
		//add new customer
		$data['customer'] = array();
		$data['customer']['name'] = $order->shipping_first_name." ".$order->shipping_last_name;
		$data['customer']['email'] = $order->billing_email;
		$data['customer']['phone'] = $order->billing_phone;
		$data['customer']['address1'] = $order->shipping_address_1;
		$data['customer']['address2'] = $order->shipping_address_2;
		$data['customer']['city'] = $order->shipping_city;
		$data['customer']['state'] = $order->shipping_state;
		$data['customer']['country'] = $order->shipping_country;
		$data['customer']['zip'] = $order->shipping_postcode;
		return json_encode($data,JSON_PRETTY_PRINT);
	}
}	
new WOE_add_customer_json();
 // add XML namespace 
add_filter("woe_xml_output_filter", function($xml,$rec) {
    $xml = str_replace('','',$xml);
    return $xml;
},10,2);
 // custom XML
add_filter("woe_xml_output_filter","woe_xml_make_order");
function woe_xml_make_order($xml) {
 // get order 
 $order = new WC_Order(WC_Order_Export_Data_Extractor::$current_order);

 //make xml
 $xml = new SimpleXMLElement( "<Order/>" );

 // top
 $xml->addChild("OrderNumber", $order->get_order_number() );
 $xml->addChild("CustomerNumber", $order->user_id );

 // addresses
 $addr = $xml->addChild("Addresses");
 $b_addr = $addr->addChild("BillingAddress");
 $b_addr->addChild("FirstName",$order->billing_first_name);
 $b_addr->addChild("LastName",$order->billing_last_name);
 $b_addr->addChild("Street", trim( $order->billing_address_1. " " . $order->billing_address_2) );
 $b_addr->addChild("Zipcode",$order->billing_postcode);
 $b_addr->addChild("City",$order->billing_city);
 $s_addr = $addr->addChild("ShippingAddress");
 $s_addr->addChild("FirstName",$order->shipping_first_name);
 $s_addr->addChild("LastName",$order->shipping_last_name);
 $s_addr->addChild("Street", trim( $order->shipping_address_1. " " . $order->shipping_address_2) );
 $s_addr->addChild("Zipcode",$order->shipping_postcode);
 $s_addr->addChild("City",$order->shipping_city);

 // items
 $items = $xml->addChild("LineItems");
 foreach ( $order->get_items('line_item') as $item_id=>$item ) {
   $product   = $order->get_product_from_item( $item );
   $item_meta = $order->get_item_meta( $item_id );

   $itemXML = $items->addChild("LineItem");
   $itemXML->addChild("Id",$product->sku);
   $itemXML->addChild("Name",$item['name']);
   $itemXML->addChild("Quantity",$item['qty']);
 }
 

 // shipment 
 $ship = $xml->addChild("LineItemShipping");
 $shipping_methods = $order->get_items( 'shipping' );
 $shipping_method = reset($shipping_methods); // take first entry
 $shipping_method_id =  !empty($shipping_method) ?  $shipping_method['method_id'] : '' ;
 $ship->addChild("Id",$shipping_method_id);
 $ship->addChild("TotalPrice",$order->get_total_shipping() );
 $ship->addChild("Name",$order->get_shipping_method() );

 // payment 
 $pay = $xml->addChild("LineItemPayment");
 $pay->addChild("Id",$order->payment_method);
 $pay->addChild("TotalPrice",$order->get_total() );
 $pay->addChild("Name",$order->payment_method_title );

 //bottom
 $xml->addChild("CreationDate", $order->order_date );
 $xml->addChild("ShippedOn", $order->completed_date );

 //format it!
 $dom = dom_import_simplexml( $xml );
 $dom->ownerDocument->formatOutput = true;
 return  $dom->ownerDocument->saveXML( $dom->ownerDocument->documentElement );
}

Actions after export

// add tags {prev_mon} and {prev_year} to filename
add_filter('woe_make_filename_replacements',function($pairs) {
	$t = strtotime("previous month");
	$pairs['{prev_mon}'] = date('m',$t);
	$pairs['{prev_year}'] = date('Y',$t);
	return $pairs;
});
// Update order status with comment
add_action('woe_order_exported', function ($order_id) {
    $order = new WC_Order($order_id);
    $order->update_status('completed', 'OK');
} ); 
// modify Content-Type for HTTP Post ( Pro version)
add_filter('wc_order_export_http_args', function ($args) {
	$args['headers']['Content-Type'] = "text/csv";
	return $args;
});

Alter summary report

// Add column "Total Orders" to "Summary by products"
class WOE_Total_Orders_Summary{
	function __construct() {
		add_filter('woe_summary_headers',function ($headers) {
			$headers[] = "Total Orders"; // just text 
			return $headers;
		});
		add_filter('woe_summary_column_keys',function ($cols) {
			$cols['count'] = 0; // new key with default value
			return $cols;
		});
		add_action('woe_summary_products_add_item',function ($key, $item, $order) {
			$_SESSION['woe_summary_products'][$key]['count'] ++; // add 1 for each order 
		},10,3);
	}	
}
new WOE_Total_Orders_Summary();

Sample addons

This section for programmers who put the changes in separate plugins. Please, review and use them as start point.
They don’t require pro version
Custom JSON format
Custom XML format
Custom CSV format

Columns for each currency

Download the plugin
This plugin was originally coded for https://classiccarbs.co.uk. They courtesy allowed to publish it for public use.

 

Sort by product names

// Sort by product name
// Format XLS
// option is ON  - "Populate other columns if products exported as rows"
class Woe_Sort_By_Product_Name {
	function __construct() {
		//add settings
		add_action("woe_settings_above_buttons", array($this,"draw_options") );
		
		// start SESSION
		add_filter("woe_settings_validate_defaults", function($settings) {
			if( !empty($settings[ 'sort_by_products' ]) ) {
				@session_start();
				
				//stop default output for rows
				add_action("woe_xls_header_filter",array($this,"init_session_data"),10,2);
				add_action("woe_xls_output_filter",array($this,"record_xls_rows"),10,2);
				add_action("woe_xls_print_footer",array($this,"sort_rows"),10,2);
			}	
			return $settings;
		});
		
	}
	// 1
	function draw_options($settings){
		$selected = !empty($settings[ 'sort_by_products' ]) ? 'checked': '';
		echo '<input type=hidden name="settings[sort_by_products]" value="0">
		<input type=checkbox name="settings[sort_by_products]" value="1" '. $selected .'>
		<span class="wc-oe-header">Sort by products,  Format XLS</span>';
	}
		
	// 2 init storage
	function init_session_data($data) {
		$_SESSION['woe_temp_rows'] = array();
		return $data;
	}

	//3 down't export rows 
	function record_xls_rows($data,$obj) {
		$_SESSION['woe_temp_rows'][] = $data;
		return false;
	}
	//4 sort and print 
	function sort_rows($phpExcel,$formatter) {
		usort($_SESSION['woe_temp_rows'], function($a,$b) {
			return $a['products_name'] < $b['products_name'] ? -1: 1; }); foreach($_SESSION['woe_temp_rows'] as $pos=>$data)
			$this->output_modified_xls($formatter,$data,$pos+2);
	}
	
	function output_modified_xls($formatter,$rec,$row) {
		$pos = 0;
		foreach ( $rec as $field => $text ) {
			$formatter->objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow( $pos, $row, $text );
			$pos++;
		}
	}
}
new Woe_Sort_By_Product_Name();

Export Products as columns

// Export Products as columns
// Format - XLS
// Checked - Output column titles as first line
// Button - Export w/o Progressbar
class Woe_Product_Columns {
    function __construct() {
        //add settings, , skip products        
        add_action("woe_settings_above_buttons", array($this,"draw_options") );
        add_filter("woe_settings_validate_defaults",array($this,"skip_products"),10,1);
    }
 
    // 1
    function draw_options($settings){
        $selected = !empty($settings[ 'products_as_columns' ]) ? 'checked': '';
        echo '<br><br>
        <input type=hidden name="settings[products_as_columns]" value="0">
        <input type=checkbox name="settings[products_as_columns]" value="1" '. $selected .'>
        <span class="wc-oe-header">Export products as columns,  print <select name="settings[products_as_columns_output_field]" style="width: 100px">
			<option value="qty">Qty</option>
			<option value="line_total">Amount</option>
        </select>
         in cell</span><br>
         Format <b>XLS</b>, button <b>Export w/o progressbar</b>
        <br><br>';
    }
    function skip_products($current_job_settings) {
        if( !empty($current_job_settings['products_as_columns']) )  {
             $current_job_settings["order_fields"]["products"]["checked"] = 0;//  just  skip standard products
             $this->output_field = $current_job_settings['products_as_columns_output_field'];
             // read orders
             add_action("woe_order_export_started",array($this,"start_new_order"),10,1);

             //stop default output for rows
             add_action("woe_xls_header_filter",array($this,"prepare_xls_vars"),10,2);
             add_action("woe_xls_output_filter",array($this,"record_xls_rows"),10,2);
             add_action("woe_xls_print_footer",array($this,"analyze_products_add_columns"),10,2);
        }
        return $current_job_settings;
    }   

        
    // 2
    function prepare_xls_vars($data) {
	$this->headers_added = count($data);
        $this->product_columns = array();
        return $data;
    }

    //3
    function start_new_order($order_id) {
        $this->order_id = $order_id;
        return $order_id;
    }
    function record_xls_rows($data,$obj) {
        $order = new WC_Order($this->order_id);
        $extra_cells = array_fill(0, count($this->product_columns), "");
        // work with products
        foreach($order->get_items('line_item') as $item_id=>$item) {
            $product_name = $item['name'];   
            $pos = array_search($product_name,$this->product_columns);
            if( $pos === false) { // new product detected
                $extra_cells[] = $item[ $this->output_field  ]; 
                $this->product_columns[] = $product_name;
            } else {
                $extra_cells[$pos] = $item[ $this->output_field  ]; 
            }
        }
        foreach($extra_cells as $pc)
            $data[] = $pc;
        return $data;
    }

    //4 
    function analyze_products_add_columns($phpExcel,$formatter) {
        // add products as titles
        foreach($this->product_columns as $pos=>$text)
            $formatter->objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow( $pos+$this->headers_added, 1, $text );
        //make first bold
        $last_column = $formatter->objPHPExcel->getActiveSheet()->getHighestDataColumn();
        $formatter->objPHPExcel->getActiveSheet()->getStyle( "A1:" . $last_column . "1" )->getFont()->setBold( true );
    }
    function output_modified_xls($formatter,$rec,$row) {
        $pos = 0;
        foreach ( $rec as $field => $text ) {
            $formatter->objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow( $pos, $row, $text );
            $pos++;
        }
    }
}
new Woe_Product_Columns();
// Pro version, send separate CSV to each seller
class Woe_Seller_CSV_mod {
	function __construct() {
		add_action("woe_test_destination", array($this,"add_hooks") );
		add_action("woe_start_cron_job_1", array($this,"add_hooks") ); // adjust job ID here 
	}
	
	function add_hooks () {
		add_action("woe_formatter_csv_start", array($this,"csv_start"),10,1);
		add_action("woe_order_export_started",array($this,"start_new_order"),10,1);
		add_action("woe_get_order_product",array($this,"detect_seller"),10,1);
		add_action("woe_formatter_set_handler_for_csv_row",array($this,"switch_file"),10,1);
		add_action("woe_formatter_csv_finished",array($this,"close_csv_files"),10,1);
		add_action("woe_custom_export_to_email",array($this,"send_csv_files"),10,4);
	}

	function csv_start($header) {
		$this->header = $header;
		$this->filenames = $this->files = array();
	}

	function start_new_order($order_id) {
		//remember sellers is for rows here 
		$this->product_sellers = array();
		$this->product_sellers_pos = 0;
                return $order_id;
	}

	function detect_seller($product) {
		$seller_id = $product->post->post_author;
		
		// remember seller  sequence for rows
		$this->product_sellers[] = $seller_id; 
		
		//put header to new file
		if( !isset($this->files[$seller_id]) ) {
			$this->filenames[$seller_id] = tempnam("/tmp",$seller_id);
			$this->files[$seller_id] = fopen( $this->filenames[$seller_id], "wb+");
			fputcsv($this->files[$seller_id], $this->header);
		}
	}

	function switch_file($handle) {
		$seller_id = $this->product_sellers[$this->product_sellers_pos++];
		return $this->files[$seller_id];
	}
	
	function close_csv_files() {
		foreach($this->files as $f)
			if(get_resource_type($f) == 'stream')
				fclose($f);
	}
	
	function send_csv_files($processed, $filename, $filepath, $exporter) {
		global $ts_mail_errors;
		
		foreach($this->filenames as $seller_id => $filepath) { // override filepath
			$user_info = get_userdata($seller_id);
			if( !empty($user_info->user_email) ) {
				$exporter->destination['email_recipients'] = $user_info->user_email;//override email
				$ts_mail_errors = array();
				echo $exporter->run_export( $filename, $filepath )."\n";
			}	
		}
		return true;
	}
}
new Woe_Seller_CSV_mod();