Since there doesn't seem to be an answer, here's my effort:
- Save your existing map, including existing text annotations.
- Delete all the layers, leaving a white screen, and the text annotations. Save it as something else, e.g. "only_labels"
- Close Qgis
- Open "only_labels.gqs" with a text editor. Notice the html/xml style format and that the text annotations have their own entries: . Within that there's an and within that mapPosX="" and mapPosY="", with the long/lats in the quotes.
- Since I don't know how to use xml data, I copied all the AnnotationItems and pasted them into Excel (libreoffice) in one long column
- Then added a counter column in front of that and trend filled from 1,2,3 to the end (I have a lot of labels). This allows me to reintegrate everything later.
- Then sorted everything by column B (the data)
- Then deleted all rows not beginning "TextAnnotationItem document=" or "AnnotationItem frameHeight=" (this removes all the junk. All we want are lat/longs & place names. I had to remove triangular brackets to post this).
- (I added a row at the top for labels, hence B2 not B1. Do the same just so you can easily copy paste) In column C, right of the AnnotationItem frameHeight rows, insert this formula: "=RIGHT(LEFT(B2,(FIND(" canvasPosY",B2)-2)),(FIND(" canvasPosY",B2)-2)-(FIND("mapPosX=",B2)+8))"
- In column D, this formula: "=RIGHT(LEFT(B2,(FIND(" frameColorAlpha",B2)-2)),(FIND(" frameColorAlpha",B2)-2)-(FIND("mapPosY=",B2)+8))"
- That's your X & Ys. Copy those formulae down all the AnnotationItem frameHeight rows.
- Right of the first TextAnnotationItem in Column F, paste this formula (which starts at row 103 for me, so change it to yours): "=LEFT((RIGHT(B103,LEN(B103)-(FIND(">",B103,FIND("pt;",B103,FIND("span style",B103)))))),(FIND("<",B103,FIND("pt;",B103,FIND("span style",B103)))-1)-(FIND(">",B103,FIND("pt;",B103,FIND("span style",B103)))))"
- Copy that down to all TextAnnotationItem cells
- Select all data, sort by counter (see item 6). It should now be alternating between TextAnnotationItem and AnnotationItem, starting with the former.
- Make cell E3 equal cell F2 (i.e. hit equals then click cell F2), this puts the location name right of the X & Y, on the same row.
- Copy that formula all the way down column E.
- Just to be safe, copy the lot & paste as value to a new sheet.
- Sort by the data (column B)
- Delete all the TextAnotationItem rows at the bottom
- Delete columns A & B, Move column C (place names) to the front, tidy any of the names up if required, save as a csv file, open in Qgis, have a beer and wish that this could be done automatically!