0

I am trying to implement ezdxf into a Flask Web-App, where I am trying to render a file and offer it as a download.

Is that possible without a database? (If not, how can I can I change the file directory of the saveas function to a web database?)

Thanks Jan

Jan
  • 1
  • 2

2 Answers2

1

You can write the DXF file to a text stream by the write method and therefore can be written into a string by using a StringIO object. StringIO.getvalue() returns an unicode string, which has to be encoded into a binary string with the correct encoding if your app needs binary encoded data.

Text encoding for DXF R2007 (AC1021) and later is always 'utf8', for older DXF versions the required encoding is stored in Drawing.encoding.

import io
import ezdxf

def to_binary_data(doc):
    stream = io.StringIO()
    doc.write(stream)
    dxf_data = stream.getvalue()
    stream.close()
    enc = 'utf-8' if doc.dxfversion >= 'AC1021' else doc.encoding
    return dxf_data.encode(enc)

doc = ezdxf.new()
binary_data = to_binary_data(doc)
mozman
  • 2,001
  • 8
  • 23
  • Thank you for the fast response! I can write the DXF File to a text stream now an can save it as a stringIO object. But when i encode it with utf-8 it just puts the strings text on my webapp. Is there any way i can put it together again as a dxf file and offer it to visitors by clicking a download button that downloads a dxf file? – Jan Dec 17 '19 at 09:17
  • 1
    This is not an ezdxf issue, this is a lack of basic knowledge how to write web apps and i can't help you by this topic. – mozman Dec 17 '19 at 09:58
0

Some more information and samples of your code will help. You can use the html A element to enable a user to download a file from their browser. You have to link the "href" property of the A element as the contents of the dxf file.

Here is an example of how to do this with ezdxf information, based on Mozman's information above too:

# Export file as string data so it can be transfered to the browser html A element href:
# Create a string io object: An in-memory stream for text I/O
stream_obj = io.StringIO()
# write the doc (ie the dxf file) to the doc stream object
doc.write(stream_obj)
# get the stream object values which returns a string
dxf_text_string = stream_obj.getvalue()
# close stream object as required by good practice
stream_obj.close()

file_data = "data:text/csv;charset=utf-8," + dxf_text_string

and then assign the "file_data" to the href property. I use Dash - Plotly callbacks and can provide you with code on how to do it in that if you want.

Or you can also use the flask.send_file function in a flask routing. This requires the data to be in binary format.

# The following code is within a flask routing 
# Create a BytesIO object
 mem = io.BytesIO()
 # Get the stringIO values as string, encode it to utf-8 and write it to the bytes object
# Create a string io object: An in-memory stream for text I/O
stream_obj = io.StringIO()
# write the doc (ie the dxf file) to the doc stream object
doc.write(stream_obj)
# The bytes object file type object is what is required for the flask.send_file method to work
 mem.write(stream_obj.getvalue().encode('utf-8'))
 mem.seek(0)
 # Close StringIO object
 stream_obj.close()

 return flask.send_file(
     mem,
     mimetype='text/csv',
     attachment_filename='drawing.dxf',
     as_attachment=True,
     cache_timeout=0
 )

I can provide you with more information if you want but you may need to provide some of your code structure to see how youre encoding and passing the data around. Thanks JF

  • [How to Answer](https://stackoverflow.com/help/how-to-answer) strongly recommends only answering well-asked questions. – Andreas Jan 30 '20 at 03:14