For avanced editing, make sure you know how to build a structure. It's not technically required, but will give you a greater amount of options in the long run.
Step 1: Build a Tree[]
You know how this works. Just build a tree. Make sure though that it's excavated and doesn't contain any grass or similar - preferably just the logs and leaves.
Step 2: Place the Floor Blocks[]
Fly below your tree and place a natural floor block directly below every log block that's supposed to be on the floor. This guide assumes your tree does not have roots and generates on top of the terrain, like vanilla trees, so these logs should all be on the same height.
Step 3: Place the Negative Space[]
Select your whole structure. You can do that by using the Block Selector, though I recommend just selecting one of the tree's log blocks with it and running /#selection wand, which will automatically select your whole tree (as long as it's excavated properly).
Then, run: /#fill reccomplex:generic_space --metadata 0 air
This will replace all the air blocks in your structure with negative space (which will, as opposed to air, not generate in the world.
Step 4: Export the Tree[]
Assuming you have your tree still selected, run #export GenericTree. It will open up a big fancy GUI that describes your structure (as copied from the GenericTree structure).
Enter a structure ID (like MyAmazingOakTree), and your name in the Metadata. Make sure the button below the structure ID says 'ACTIVE'.
Find the line that says 'Generation' and click edit. There will already be two entries inside.
Decoration[]
If you want your tree to generate in the world on natural generation, you need a vanilla decoration generation info. Find the line that says 'Vanilla Decoration' and click Edit.
Most importantly, there are the biomes and dimensions, where you can set where your tree occurs. If you're going for something simple, I recommend finding a preset at the top for both that fits your thing, like Overworld for dimensions and Oak Trees for biomes.
You can leave all the other options be for now.
Sapling[]
If you want your tree to grow from saplings, you need a sapling generation info. Find the line that says 'Sapling' and click Edit.
Important here are the Pattern and Ingredients. In the pattern you specify the shape the saplings need to be arranged at, and in the ingredients you set what specific blocks you accept for the shape.
By default, the pattern should contain one rectangle spanning over 2 blocks (6, 1, 5 to 6, 1, 6, relative to the structure origin (e.g. 0, 0, 0 is the northernmost, westernmost, lowest block in the structure)). That means that for the GenericTree, the saplings would be located next to each other at 6, 1, 5 and 6, 1, 6 (relati for the tree to spawn. Figure out where your tree would require saplings and change the coordinates to match that. Don't worry if you forgot how it looked exactly, you can always skip this step and come back to it later using #edit.
The Ingredients should contain just one entry with the name 'Sapling'. It accepts the sapling block with the type oak. If you want another type of sapling, change the type to, for example, $[type]=birch. For custom saplings, change the ID and the type. It might be useful to use the Inspector to see what ID, property key and property value you specifically need for that sapling.
You can, again, keep all the other options as they are for now.
Exporting[]
You can now click on 'Save'. This is pretty much it. Your tree should now generate on world generation and grow from saplings.