I want to export all records of a given content type to a csv file. I've checked some allready existing stuff to do this but nothing really meets my demands or have functionality I do not wish to add.

I'm new to drupal and made some basic custom modules allready so I also want to make a module that does this from scratch so I learn stuff instead of using pre-made stuff and having no clue whats going on.

When you go to the module you see a dropdown box filled with all the content types in my system (This is working). When I select a content type I want a table with all the records of that content type.

under this table I want a button Export to CSV. when This is pressed a download screen should popup. Im only puzzled on how to make the .CSV file with PHP.

The dropdown list and the generated table is almost working as we speak.

anybody that can help me?

Comments

dman’s picture

Well, if you really think this is easier than using the popular, tested solution then the quick answer is:

Now you put all the data you fetched into a string, separated by commas.
print it, followed by a newline.
Repeat until done.
die();

or, if you want to force a download instead of a screen view, set the HTTP content-type headers to something like "application/text+csv" before starting to print.

... then go back and realize that you probably need to quote your strings before making a CSV.

... continue. There is also a PEAR library that can help, but really, outputting a CSV string is not that hard.
Exactly what bit are you stuck on?

Fons Vandamme’s picture

I'm not looking for the easiest way to achieve this, I want to tailor this module for the purpose I need it for.. I also feel like I need to take the time to make this on my own in order to learn more about drupal module development.

The pieces of the puzzle don't fit at the moment, that is my main issue. I made a module with a menu hook that has a callback to a form. This form has a dropdown filled with all the content types in my installation. When I choose a content type the string you talk about should be created.

It would be nice if a table now shows under this dropdown with the content in the string. I can use AHAH to dynamically do this. But how do I add this to my form? how do I show html stuff in a form without it being one of the form types (select, textarea, ...).

Under this table a button is made 'download CSV', when this button is pressed a CSV file should be offered. This CSV file contains all the records of the selected content type.

I hope you get the main idea..

Thanks for your time and support!

dman’s picture

how do I show html stuff in a form without it being one of the form types (select, textarea, ...).

'#type' => 'markup'.
... though for your purposes, I'd suggest using a textarea anyway.

Not sure of the advantage of mixing it up with AHAH just yet, get it working normally first I'd say.

For the download action, you can attach a unique #submit function to the button. That would call another submit handler (or even the same form_submit if you check the 'op' or $form_state['clicked_button']['#id'] value). And that version of the submit handler would return the raw text.
That's the broad strikes, anyway. Poke around the FormAPI docs a bit. It's probably quite a good getting-to-know FAPI project.

Fons Vandamme’s picture

thanks for your information. I'm finishing up a module now so I'll give the stuff you suggest a try tomorrow as I have plenty of time to really dig into it then. I'll keep you posted ;)

thanks again for your answers, I hope one day i'll master all this stuff well enough to pass it on!

Fons Vandamme’s picture

The dropdown is filled now, when I select a content type in it then all nodes of that content type are returned:

$keuze = the content type

$nodes = db_query("SELECT * FROM {node} WHERE type = '%s'", $keuze);

Still figuring out now how I get all data of these nodes now cause now I only have the nid, vid, type, language, title, uid, status, created, changed, comment, promote, moderate, sticky, tnid and translate with this query. I use CCK for all my content types by the way which is making it harder cause I reuse fields.

dman’s picture

Well yeah, that's what you asked for.
Just select the nid, then node_load($nid); to get a full load of data.
Take it from there.

Fons Vandamme’s picture

thanks, one step further now.. yeah true I asked to bump into stuff like this.. on the other hand i'm learning alot now instead of using a module and not knowing whats going on.

It's the price you pay, I guess!

Fons Vandamme’s picture

okay, my CSV string is ready... I just printed it with dsm($string) and it is generated correctly for all my content types. Now I need to find a way to get this in a file that is offered to the user.. any clue how I can do that?

dman’s picture

As I said earlier.
Set a header http://php.net/manual/en/function.header.php

<?php
 header
('Content-Disposition: attachment; filename="downloaded.csv"');
?>

print your string, then exit.

Jaypan’s picture

Fileforce download scripts can be done as easily as with the code above, though adding more headers makes everything work smoother.

This is a script I've used in the past (outside Drupal) that works really well: http://w-shadow.com/blog/2007/08/12/how-to-force-file-download-with-php/

I will soon be leaving the Drupal forums permanently. To understand why, please see this thread.

Fons Vandamme’s picture

wow! thanks alot, never realised it was that easy!

header('Content-Disposition: attachment; filename="export.csv"');
print($csv);
exit;

works like a charm!

One more problem: When using a textarea where you have stuff typed on different lines it copies this string on different lines in the CSV file. I tried to trim it out on \n but that doesn't seem to work.

Fons Vandamme’s picture

issue resolved:

str_replace("\r\n", " ", $veld[0]['value'])