Which version of QGIS are you using? If it's 2.4, you can set the columns shown in a QgsComposerAttributeTable by using the setColumns method. This method takes a list of QgsComposerTableColumn. Here's an example
#create a composition and composer attribute table
composition = QgsComposition(iface.mapCanvas().mapSettings())
table = QgsComposerAttributeTable(composition)
#create columns for the table
col1 = QgsComposerTableColumn()
col1.setAttribute('feature_id')
col2 = QgsComposerTableColumn()
col2.setAttribute('feature_name')
#set table columns
table.setColumns([col1, col2])
There's a bunch of other things you can set for columns, such as the heading, alignment and sort order (see api docs here). You can even set an expression for a column in place of the attribute for added flexibility.
edit:
To show only certain features you can set a filter on the table:
table.setFeatureFilter("id in (1,2,3)")
table.setFilterFeatures( True )
So, to filter a table to only selected features:
#get current layer
current_layer = qgis.utils.iface.mapCanvas().currentLayer()
#get list of selected feature ids
selected_ids = [f.id() for f in current_layer.selectedFeatures()]
#convert list to string
filter_id_string = ','.join([str(id) for id in selected_ids])
#filter table
table.setFeatureFilter("$id in (" + filter_id_string + ")")
table.setFilterFeatures( True )
update:
I missed a character in the filter expression. It should have been "$id in (...". Here's a complete, working version of the code you posted. There was a few simple mistakes (the constructor for QgsLegendModel takes no arguments, there's no applyDefaultSize method for attribute tables, and I've also moved the attribute table setItemPosition line):
from PyQt4.QtCore import *
from PyQt4.QtGui import *
layer = qgis.utils.iface.activeLayer()
qgis.utils.iface.actionZoomToSelected().trigger()
qgis.utils.iface.mapCanvas().zoomScale(1000)
mapRenderer = iface.mapCanvas().mapRenderer()
c = QgsComposition(mapRenderer)
c.setPlotStyle(QgsComposition.Print)
x, y = 0, 0
w, h = c.paperWidth(), c.paperHeight()
composerMap = QgsComposerMap(c, x,y,w*.75,h)
c.addItem(composerMap)
legend = QgsComposerLegend(c)
c.addComposerLegend(legend)
legend.model().setLayerSet(mapRenderer.layerSet())
legend.setTitle('')
legendModel = QgsLegendModel()
legendModel.setLayerSet([layer.id()])
legend.updateLegend()
selected_ids = [f.id() for f in layer.selectedFeatures()]
filter_id_string = ','.join([str(id) for id in selected_ids])
table = QgsComposerAttributeTable(c)
table.setItemPosition(x+50, y+50)
table.setVectorLayer(layer)
table.setMaximumNumberOfFeatures(20)
table.setFeatureFilter("$id in (" + filter_id_string + ")")
table.setFilterFeatures(True)
col1 = QgsComposerTableColumn()
col1.setAttribute('Diametre')
col1.setHeading("Diametre")
col2 = QgsComposerTableColumn()
col2.setAttribute('Nature')
col2.setHeading("Nature")
table.setColumns([col1, col2])
c.addItem(table)
printer = QPrinter()
printer.setOutputFormat(QPrinter.PdfFormat)
printer.setOutputFileName('out.pdf')
printer.setPaperSize(QSizeF(c.paperWidth(), c.paperHeight()), QPrinter.Millimeter)
printer.setFullPage(True)
printer.setColorMode(QPrinter.Color)
printer.setResolution(c.printResolution())
pdfPainter = QPainter(printer)
paperRectMM = printer.pageRect(QPrinter.Millimeter)
paperRectPixel = printer.pageRect(QPrinter.DevicePixel)
c.render(pdfPainter, paperRectPixel, paperRectMM)
pdfPainter.end()
To avoid changing the scale and/or position of the map, you can lock the map item in the items panel of print compose. This will avoid making any accidental changes.
Closing QGIS, without saving the project, should also have enabled you to get back to the previous configuration.
Best Answer
I've seen that blog post too, and wondered the same thing!
You could use HTML Frames and the D3 library, if you don't mind doing a bit of JavaScript.
Here's an example which I hard-coded. You can insert QGIS Expressions into your page source (from QGIS 2.14 or later)
In my case, I've saved the html file locally and hacked it until I got it to display, using browser's developer tools.
Once you have it working, you should be able to paste the page source into the 'source' text box directly, and drop QGIS expressions in (such as field values, variables etc.) using the Insert an expression button.
I cobbled together that example from alignedleft.com. This tutorial is useful as it shows how to build bar charts from simple lists; most examples I've seen use separate TSV files.
Bl.ocks.org has a very large set of examples.
You can get code for the AlignedLeft tutorials here on GitHub
This might make a good plugin... I see there are a couple of d3 plugins already, although I've not had a chance to try them - worth a look maybe?