C# Revit二次开发 地层工程量统计

复制代码
<ui:CCWindow  x:Class="Bhidi.Revit.CalculateEarthworkVolume.Views.MainWindow"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Bhidi.Revit.CalculateEarthworkVolume.Views"
             mc:Ignorable="d" 
              
             xmlns:ui="clr-namespace:CC.Style;assembly=CC.Style"
xmlns:hc="https://handyorg.github.io/handycontrol"
xmlns:vm ="clr-namespace:Bhidi.Revit.CalculateEarthworkVolume.ViewModel"
 d:DataContext="{d:DesignInstance Type=vm:MainViewModel}"
xmlns:GridHelper="clr-namespace:Bhidi.Revit.Tools" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
Height="800" Width="543"
MinHeight="800" MinWidth="543"
              Title="计算地层工程量"
              >

    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml" />
                <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml" />
                <ResourceDictionary Source="pack://application:,,,/CC.Style;component/CCTheme.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Viewbox Stretch="UniformToFill">
        <Canvas Height="800" Width="543">
            <Grid Height="800" Width="543" GridHelper:GridHelper.Rows="4" GridHelper:GridHelper.RowHeights="*,7*,3*,*" >
                <Grid Grid.Row="0" >
                    <GroupBox Header="选择范围" Height="50" Margin="8" VerticalAlignment="Top" ></GroupBox>

                    <TextBox x:Name="textBoxOne" HorizontalAlignment="Left" Height="22" Margin="15,27,0,0" TextWrapping="Wrap" 
 Text="{Binding LocationsText5}" VerticalAlignment="Top" Width="410" IsEnabled="False" />

                    <Button  Content="选择" HorizontalAlignment="Left" Margin="445,23,0,0" VerticalAlignment="Top" 
Width="67"  Command="{Binding PickCmd}" Height="25" Style="{StaticResource MessageBoxPrimaryButtonStyle}" />

                </Grid>
                <Grid Grid.Row="1">
                    <GroupBox Header="工程量明细" Grid.Row="1" Margin="8,0,8,0">
                        <DataGrid 
x:Name="dg1"
CanUserAddRows="False"
CanUserSortColumns="False"
SelectionMode="Single"
Style="{StaticResource BaseDG}"
ColumnHeaderStyle="{DynamicResource ColumnHeaderCenter}"
ItemsSource="{Binding EarthVolumns,IsAsync=True}"
                            SelectedItem="{Binding SelectedElement, Mode=TwoWay}"
                            Margin="0,6"
>
                            <DataGrid.Columns>
                                <DataGridTextColumn Width="50"  Header="序号" Binding="{Binding OrderNumber}"  ElementStyle="{StaticResource CenterAlignmentStyle}"  />
                                <DataGridTextColumn Width="*"  Header="地层名称" Binding="{Binding EarthName}"  ElementStyle="{StaticResource CenterAlignmentStyle}"  />
                                <DataGridTextColumn Width="*"  Header="地层材质" Binding="{Binding EarthMaterial}" ElementStyle="{StaticResource CenterAlignmentStyle}" />
                                <DataGridTextColumn Width="*"  Header="体积(m³)" Binding="{Binding Volumn}" ElementStyle="{StaticResource CenterAlignmentStyle}" />
                            </DataGrid.Columns>
                        </DataGrid>
                    </GroupBox>
                </Grid>
                <Grid Grid.Row="2">
                    <GroupBox Header="工程量汇总" Grid.Row="1" Margin="8,0,8,0">
                        <DataGrid 
x:Name="dg2"
CanUserAddRows="False"
CanUserSortColumns="False"
SelectionMode="Single"
Style="{StaticResource BaseDG}"
ColumnHeaderStyle="{DynamicResource ColumnHeaderCenter}"
ItemsSource="{Binding SumEarthVolumns,IsAsync=True}"
                            Margin="0,6"
>
                            <DataGrid.Columns>
                                <DataGridTextColumn Width="50"  Header="序号" Binding="{Binding OrderNumber}"  ElementStyle="{StaticResource CenterAlignmentStyle}"  />
                                <DataGridTextColumn Width="*"  Header="地层材质" Binding="{Binding EarthMaterial}" ElementStyle="{StaticResource CenterAlignmentStyle}" />
                                <DataGridTextColumn Width="*"  Header="汇总体积(m³)" Binding="{Binding Volumn}" ElementStyle="{StaticResource CenterAlignmentStyle}" />
                            </DataGrid.Columns>
                        </DataGrid>
                    </GroupBox>


                </Grid>
                <Grid Grid.Row="3"  >
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,0,8,15" >
                        <Button Content="导出明细" Command="{Binding ExportDetailCommand}" Style="{StaticResource MessageBoxPrimaryButtonStyle}" Visibility="{Binding CreateVisibility}" Margin="8,0,0,0" />
                        <Button Content="导出汇总" Command="{Binding ExportCommand}" Style="{StaticResource MessageBoxPrimaryButtonStyle}" Visibility="{Binding CreateVisibility}" Margin="8,0,0,0" />
                        <Button Click="CloseWindow" IsCancel="True" Style="{StaticResource MessageBoxButtonStyle}"  Margin="8,0,0,0"/>
                    </StackPanel>
                </Grid>
            </Grid>
        </Canvas>
    </Viewbox>
</ui:CCWindow>

using Autodesk.Internal.Windows.ToolBars;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.ExtensibleStorage;
using Autodesk.Revit.UI.Selection;
using Bhidi.Revit.CalculateEarthworkVolume.Model;
using CC.Style;
using CC.Utils.Extensions;
using CC.Utils.Models;
using CC.Utils.Tools;
using CheckLocation.CreateInstallationRoomLayer.Extensions;
using CheckLocation.CreateTrafficCableHole.Model;
using GalaSoft.MvvmLight.Command;
using Microsoft.Win32;
using MySqlX.XDevAPI;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using static CC.ExpandPack.Rebar_CommonUtil.CommonUtils;

namespace Bhidi.Revit.CalculateEarthworkVolume.ViewModel
{
    public class MainViewModel : CCViewModelBase
    {
        public MainViewModel()
        {
            Init();
        }
        /// <summary>
        /// 界面参数初始化
        /// </summary>
        private void Init()
        {
            Document doc = UIdoc.Document;

            LocationsText5 = "请选择一个体量作为工程量计算范围。";

            EarthVolumns = new ObservableCollection<EarthVolumn>();
            SumEarthVolumns = new ObservableCollection<SumEarthVolumn>();





        }

        private string locationsText5;
        public string LocationsText5 { get => locationsText5; set { Set(ref locationsText5, value); } }

        private ObservableCollection<EarthVolumn> earthVolumns;
        public ObservableCollection<EarthVolumn> EarthVolumns
        { get => earthVolumns; set { Set(ref earthVolumns, value); } }

        private ObservableCollection<SumEarthVolumn> sumEarthVolumns;
        public ObservableCollection<SumEarthVolumn> SumEarthVolumns
        { get => sumEarthVolumns; set { Set(ref sumEarthVolumns, value); } }


        private EarthVolumn selectedElement;

        public EarthVolumn SelectedElement 
        { 
            get => selectedElement; 
            set 
            { 
                Set(ref selectedElement, value);

                //UIdoc.Selection.SetElementIds(new List<ElementId> { SelectedElement.EarthId});
                UIdoc.Selection.SetElementIds(SelectedElement.EarthId.XToList());

                

            } 
        }


        //PickCmd
        private RelayCommand pickCmd;
        public ICommand PickCmd
        {
            get
            {
                if (pickCmd == null)
                {
                    pickCmd = new RelayCommand(PerformGetFamily);
                }
                return pickCmd;
            }
        }

        private void PerformGetFamily()
        {
            Document doc = UIdoc.Document;

            CCDoc.Instance.Task.RunAsync(app =>
            {
                doc.Invoke(t =>
                {
                    GetFamily();

                }, "选择体量族");

            });
        }

        private void GetFamily()
        {
            Document doc = UIdoc.Document;

            //清除表格数据
            EarthVolumns.Clear();
            SumEarthVolumns.Clear();

            Reference reference = UIdoc.Selection.PickObject(ObjectType.Element, new FormSelectionFilter());
            FamilyInstance instance = doc.GetElement(reference) as FamilyInstance;
            ElementId insId = instance.Id;
            Element insEle = insId.ToElement(doc);

            //名字返回前台
            LocationsText5 = instance.Name;

            //范围体量只有一个实体Solid,放心用FirstOrDefault
            Solid solid = instance.GetSolids().FirstOrDefault();

            //获取与Solid相交的所有体量
            List<Element> eles2 = GetMassesIntersectingSolid(doc, solid);
            List<Element> eles = new List<Element>();
            foreach (var ele in eles2)
            {
                if (ele.Id != insId)
                {
                    eles.Add(ele);
                }
            }


            List<ElementId> elementIds = eles.ToElementIds();


            if (elementIds.Count == 0)
            {
                MessageBox.Show("范围框内无任何地层模型!");
                return;
            }

            //高亮显示相交的体量
            UIdoc.Selection.SetElementIds(elementIds);

            //存在错误Solid
            bool IsHaveBadSolid = false;

            try
            {
                for (int i = 0; i < eles.Count; i++)
                {
                    Element ele = eles[i];
                    //地层中的每一块Solid
                    List<Solid> massSolids = ele.GetSolids();
                    double sumVolumn = 0.0;
                    foreach (var massSolid in massSolids)
                    {
                        Solid interSolid = null;
                        double volumn = 0.0;
                        try
                        {
                            interSolid = BooleanOperationsUtils.ExecuteBooleanOperation(solid, massSolid, BooleanOperationsType.Intersect);
                            if (interSolid != null)
                            {
                                volumn = interSolid.Volume.CuftToM3();
                            }
                        }
                        catch (Autodesk.Revit.Exceptions.InvalidOperationException)
                        {
                            //存在问题模型
                            massSolid.Draw(doc);
                            //Solid可能有问题,不能求出交集,体积也不好算,提示下得了
                            IsHaveBadSolid = true;


                            //切片积分法对相交的Solid进行了体积试算
                            //double vvv = GetIntersectionVolume(doc, solid, massSolid).CuftToM3();
                            //MessageBox.Show(vvv.ToString());



                        }

                        sumVolumn = sumVolumn + volumn;
                    }

                    //获取族类型材质
                    string materialName = "";
                    FamilySymbol familySymbol = (ele as FamilyInstance).Symbol;
                    Parameter typeMaterialParam = familySymbol.LookupParameterByName("材质");
                    if (typeMaterialParam != null && typeMaterialParam.HasValue)
                    {
                        ElementId materialId = typeMaterialParam.AsElementId();
                        if (materialId != null && materialId != ElementId.InvalidElementId)
                        {
                            Material material = doc.GetElement(materialId) as Material;
                            materialName = material.Name;
                        }
                    }

                    EarthVolumns.Add(new EarthVolumn() { OrderNumber = $"{i + 1}", EarthName = $"{ele.Name}", EarthMaterial = materialName, Volumn = Math.Round(sumVolumn, 3),EarthId = ele.Id });


                }

            }
            catch (Exception)
            {


            }
            //将EarthVolumns整理成SumEarthVolumns,通过材质合并体积
            var sum = EarthVolumns.GroupBy(x => x.EarthMaterial).Select(g => new EarthVolumn { EarthMaterial = g.Key, Volumn = g.Sum(x => x.Volumn) }).ToList();

            for (int i = 0; i < sum.Count; i++)
            {
                SumEarthVolumns.Add(new SumEarthVolumn() { OrderNumber = $"{i + 1}", EarthMaterial = sum[i].EarthMaterial, Volumn = Math.Round(sum[i].Volumn, 3) });
            }


            if (IsHaveBadSolid)
            {
                MessageBox.Show("存在无法计算地层,请检查!");
            }


        }

        //ExportCommand
        private RelayCommand export;

        public ICommand ExportCommand
        {
            get
            {
                if (export == null)
                {
                    export = new RelayCommand(PerformExport);
                }
                return export;
            }
        }

        private void PerformExport()
        {
            Document doc = UIdoc.Document;

            CCDoc.Instance.Task.RunAsync(app =>
            {
                doc.Invoke(t =>
                {

                    ExportData();

                }, "导出工程量汇总");

            });
        }

        private async void ExportData()
        {
            Document doc = UIdoc.Document;

            HelperExcel helperExcel = new HelperExcel();
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            saveFileDialog.Filter = "Excel(*.xls,*.xlsx)|*.xls;*.xlsx";

            if (saveFileDialog.ShowDialog() == true)
            {
                var path = saveFileDialog.FileName;

                var isSucceed = await helperExcel.ExportExcelAsync(path, SumEarthVolumns);
                if (isSucceed)
                {
                    if (MessageBox.Show($"导出完成,是否打开文件?", "导出完成", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                    {
                        Process.Start(path);
                    }
                }
            }


        }

        //ExportDetailCommand
        private RelayCommand exportDetail;

        public ICommand ExportDetailCommand
        {
            get
            {
                if (exportDetail == null)
                {
                    exportDetail = new RelayCommand(PerformExportDetail);
                }
                return exportDetail;
            }
        }

        private void PerformExportDetail()
        {
            Document doc = UIdoc.Document;

            CCDoc.Instance.Task.RunAsync(app =>
            {
                doc.Invoke(t =>
                {

                    ExportDataDetail();

                }, "导出工程量汇总");

            });
        }

        private async void ExportDataDetail()
        {
            Document doc = UIdoc.Document;

            HelperExcel helperExcel = new HelperExcel();
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            saveFileDialog.Filter = "Excel(*.xls,*.xlsx)|*.xls;*.xlsx";

            if (saveFileDialog.ShowDialog() == true)
            {
                var path = saveFileDialog.FileName;

                var isSucceed = await helperExcel.ExportDetailExcelAsync(path, EarthVolumns);
                if (isSucceed)
                {
                    if (MessageBox.Show($"导出完成,是否打开文件?", "导出完成", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                    {
                        Process.Start(path);
                    }
                }
            }


        }

        


        #region 切片积分法-试算
        /// <summary>
        /// 切片积分法求两个Solid的相交体积(纯布尔运算,无任何不存在的API)
        /// </summary>
        public static double GetIntersectionVolume(Document doc, Solid solid1, Solid solid2, int sliceCount = 200)
        {
            // ----- 1. 无效检查 -----
            if (solid1 == null || solid2 == null ||
                solid1.Faces.Size == 0 || solid2.Faces.Size == 0)
                return 0.0;

            // ----- 2. 世界坐标系包围盒(修正Transform)-----
            BoundingBoxXYZ bbox1 = GetWorldBoundingBox(solid1);
            BoundingBoxXYZ bbox2 = GetWorldBoundingBox(solid2);
            if (bbox1 == null || bbox2 == null) return 0.0;

            // ----- 3. Z轴交叠范围 -----
            double zMin = Math.Max(bbox1.Min.Z, bbox2.Min.Z);
            double zMax = Math.Min(bbox1.Max.Z, bbox2.Max.Z);
            if (zMax <= zMin + 1e-9) return 0.0;

            // ----- 4. XY平面交叠矩形(限制薄片范围,提高性能)-----
            double xyMinX = Math.Max(bbox1.Min.X, bbox2.Min.X);
            double xyMinY = Math.Max(bbox1.Min.Y, bbox2.Min.Y);
            double xyMaxX = Math.Min(bbox1.Max.X, bbox2.Max.X);
            double xyMaxY = Math.Min(bbox1.Max.Y, bbox2.Max.Y);
            if (xyMaxX <= xyMinX || xyMaxY <= xyMinY) return 0.0;

            double sliceHeight = (zMax - zMin) / sliceCount;
            double totalVolume = 0.0;

            // ----- 5. 主循环:每片独立布尔交 -----
            for (int i = 0; i < sliceCount; i++)
            {
                double zCenter = zMin + (i + 0.5) * sliceHeight;

                // --- 核心修正:手工构造矩形CurveLoop(4条Line)---
                CurveLoop profile = new CurveLoop();
                double halfHeight = sliceHeight * 0.5;

                // 矩形的四个角点(在Z=zCenter平面上)
                XYZ p1 = new XYZ(xyMinX, xyMinY, zCenter - halfHeight); // 左下
                XYZ p2 = new XYZ(xyMaxX, xyMinY, zCenter - halfHeight); // 右下
                XYZ p3 = new XYZ(xyMaxX, xyMaxY, zCenter - halfHeight); // 右上
                XYZ p4 = new XYZ(xyMinX, xyMaxY, zCenter - halfHeight); // 左上

                // 四条边必须首尾相连,形成闭合环
                profile.Append(Line.CreateBound(p1, p2));
                profile.Append(Line.CreateBound(p2, p3));
                profile.Append(Line.CreateBound(p3, p4));
                profile.Append(Line.CreateBound(p4, p1));

                // --- 拉伸成薄片立方体 ---
                // CreateExtrusionGeometry 需要 IList<CurveLoop>,用数组包装
                IList<CurveLoop> profileLoops = new List<CurveLoop> { profile };
                Solid thinSlice = null;
                try
                {
                    thinSlice = GeometryCreationUtilities.CreateExtrusionGeometry(
                        profileLoops,
                        XYZ.BasisZ,
                        sliceHeight);
                }
                catch
                {
                    continue; // 拉伸失败,跳过此片
                }

                if (thinSlice == null || thinSlice.Faces.Size == 0) continue;

                // --- 薄片与Solid1求交 ---
                Solid slice1 = null;
                try { slice1 = BooleanOperationsUtils.ExecuteBooleanOperation(thinSlice, solid1, BooleanOperationsType.Intersect); }
                catch { }
                if (slice1 == null || slice1.Faces.Size == 0 || slice1.Volume < 1e-12) continue;

                // --- 薄片与Solid2求交 ---
                Solid slice2 = null;
                try { slice2 = BooleanOperationsUtils.ExecuteBooleanOperation(thinSlice, solid2, BooleanOperationsType.Intersect); }
                catch { }
                if (slice2 == null || slice2.Faces.Size == 0 || slice2.Volume < 1e-12) continue;

                // --- 两个薄片相交,得到最终交集薄片 ---
                Solid intersectSlice = null;
                try
                {
                    intersectSlice = BooleanOperationsUtils.ExecuteBooleanOperation(slice1, slice2, BooleanOperationsType.Intersect);


                }
                catch { }
                if (intersectSlice == null || intersectSlice.Faces.Size == 0) continue;

                totalVolume += intersectSlice.Volume;
            }

            return totalVolume;
        }

        /// <summary>
        /// 获取Solid在世界坐标系下的包围盒(修正Transform)
        /// </summary>
        private static BoundingBoxXYZ GetWorldBoundingBox(Solid solid)
        {
            BoundingBoxXYZ bbox = solid.GetBoundingBox();
            if (bbox == null) return null;

            if (!bbox.Transform.IsIdentity)
            {
                XYZ worldMin = bbox.Transform.OfPoint(bbox.Min);
                XYZ worldMax = bbox.Transform.OfPoint(bbox.Max);
                BoundingBoxXYZ worldBBox = new BoundingBoxXYZ();
                worldBBox.Min = worldMin;
                worldBBox.Max = worldMax;
                worldBBox.Transform = Transform.Identity;
                return worldBBox;
            }
            return bbox;
        }


        #endregion


















        /// <summary>
        /// 获取与Solid相交的所有体量
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="targetSolid"></param>
        /// <returns></returns>
        public List<Element> GetMassesIntersectingSolid(Document doc, Solid targetSolid)
        {
            List<Element> intersectingMasses = new List<Element>();

            // 获取所有体量
            FilteredElementCollector collector = new FilteredElementCollector(doc)
                .OfCategory(BuiltInCategory.OST_Mass)
                .WhereElementIsNotElementType();

            Options options = new Options();
            options.ComputeReferences = true;
            options.DetailLevel = ViewDetailLevel.Fine;

            foreach (Element mass in collector)
            {
                bool intersects = CheckIntersection(mass, targetSolid, options);

                if (intersects)
                {
                    intersectingMasses.Add(mass);
                }
            }

            return intersectingMasses;
        }

        /// <summary>
        /// 检测体量与Solid是否相交
        /// </summary>
        private bool CheckIntersection(Element element, Solid targetSolid, Options options)
        {
            try
            {
                GeometryElement geometry = element.get_Geometry(options);

                foreach (GeometryObject geoObj in geometry)
                {
                    Solid solid = null;

                    if (geoObj is Solid directSolid)
                    {
                        solid = directSolid;
                    }
                    else if (geoObj is GeometryInstance instance)
                    {
                        GeometryElement instanceGeometry = instance.GetInstanceGeometry();
                        foreach (GeometryObject instObj in instanceGeometry)
                        {
                            if (instObj is Solid s && s.Volume > 0)
                            {
                                solid = s;
                                break;
                            }
                        }
                    }

                    if (solid != null && solid.Volume > 0)
                    {
                        // 检查相交
                        Solid intersection = BooleanOperationsUtils.ExecuteBooleanOperation(
                            targetSolid,
                            solid,
                            BooleanOperationsType.Intersect
                        );

                        if (intersection != null && intersection.Volume > 0)
                        {
                            return true;
                        }
                    }
                }
            }
            catch
            {
                // 忽略几何错误
            }

            return false;
        }



    }

    /// <summary>
    /// 设定选择只能是体量
    /// </summary>
    public class FormSelectionFilter : ISelectionFilter
    {
        public bool AllowElement(Element elem)
        {
            if (elem.Category.Name == "体量")
                return true;
            else return false;
        }

        public bool AllowReference(Reference reference, XYZ position)
        {
            return false;
        }
    }



}

using Autodesk.Revit.DB;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Bhidi.Revit.CalculateEarthworkVolume.Model
{
    public class EarthVolumn
    {
        private string orderNumber;

        private string earthName;

        private string earthMaterial;

        private double volumn;

        private ElementId earthId;
        public string OrderNumber { get => orderNumber; set => orderNumber = value; }
        public string EarthName { get => earthName; set => earthName = value; }
        public string EarthMaterial { get => earthMaterial; set => earthMaterial = value; }
        public double Volumn { get => volumn; set => volumn = value; }

        public ElementId EarthId { get => earthId; set => earthId = value; }








    }
}

using CC.Utils.Tools;
using Microsoft.WindowsAPICodePack.Shell.Interop;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using HorizontalAlignment = NPOI.SS.UserModel.HorizontalAlignment;
using VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment;

namespace Bhidi.Revit.CalculateEarthworkVolume.Model
{
    public class HelperExcel
    {
        public async Task<bool> ExportExcelAsync(string path, ObservableCollection<SumEarthVolumn> SumEarthVolumns)
        {
            return await Task.Run(() =>
            {
                try
                {
                    var workbook = new HSSFWorkbook();

                    var sheet = workbook.CreateSheet();

                    // 创建字体
                    IFont font = workbook.CreateFont();
                    font.FontHeightInPoints = 10; // 字体大小
                    font.FontName = "宋体"; // 字体名称
                    // 创建样式
                    ICellStyle centerStyle = workbook.CreateCellStyle();
                    centerStyle.Alignment = HorizontalAlignment.Center;
                    centerStyle.VerticalAlignment = VerticalAlignment.Center;
                    centerStyle.SetFont(font);
                    // 创建样式
                    ICellStyle LcenterStyle = workbook.CreateCellStyle();
                    LcenterStyle.Alignment = HorizontalAlignment.Left;
                    LcenterStyle.VerticalAlignment = VerticalAlignment.Center;
                    LcenterStyle.SetFont(font);

                    sheet.SetColumnWidth(0, 10 * 256);
                    sheet.SetColumnWidth(1, 36 * 256);
                    sheet.SetColumnWidth(2, 36 * 256);

                    var row = sheet.CreateRow(0);
                    row.Height = 20 * 20;

                    row.CreateCell(0).SetCellValue("序号");
                    row.CreateCell(1).SetCellValue("地层材质");
                    row.CreateCell(2).SetCellValue("汇总体积(m³)");

                    row.GetCell(0).CellStyle = centerStyle;
                    row.GetCell(1).CellStyle = centerStyle;
                    row.GetCell(2).CellStyle = centerStyle;
                    


                    var quantitiesSummaries = SumEarthVolumns;
                    for (int j = 0; j < quantitiesSummaries.Count; j++)
                    {
                        try
                        {
                            var quantitiesSummary = quantitiesSummaries[j];
                            row = sheet.CreateRow(j + 1);
                            row.Height = 20 * 20;
                            row.CreateCell(0).SetCellValue(quantitiesSummary.OrderNumber);
                            row.CreateCell(1).SetCellValue(quantitiesSummary.EarthMaterial);
                            row.CreateCell(2).SetCellValue(quantitiesSummary.Volumn);
                            

                            row.GetCell(0).CellStyle = centerStyle;
                            row.GetCell(1).CellStyle = centerStyle;
                            row.GetCell(2).CellStyle = centerStyle;
                            
                        }
                        catch (Exception)
                        {
                        }
                    }


                    using (var fileStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
                    {
                        workbook.Write(fileStream);
                        fileStream.Close();
                    }
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                    return false;
                }

                return true;
            });
        }

        public async Task<bool> ExportDetailExcelAsync(string path, ObservableCollection<EarthVolumn> SumEarthVolumns)
        {
            return await Task.Run(() =>
            {
                try
                {
                    var workbook = new HSSFWorkbook();

                    var sheet = workbook.CreateSheet();

                    // 创建字体
                    IFont font = workbook.CreateFont();
                    font.FontHeightInPoints = 10; // 字体大小
                    font.FontName = "宋体"; // 字体名称
                    // 创建样式
                    ICellStyle centerStyle = workbook.CreateCellStyle();
                    centerStyle.Alignment = HorizontalAlignment.Center;
                    centerStyle.VerticalAlignment = VerticalAlignment.Center;
                    centerStyle.SetFont(font);
                    // 创建样式
                    ICellStyle LcenterStyle = workbook.CreateCellStyle();
                    LcenterStyle.Alignment = HorizontalAlignment.Left;
                    LcenterStyle.VerticalAlignment = VerticalAlignment.Center;
                    LcenterStyle.SetFont(font);

                    sheet.SetColumnWidth(0, 10 * 256);
                    sheet.SetColumnWidth(1, 36 * 256);
                    sheet.SetColumnWidth(2, 36 * 256);
                    sheet.SetColumnWidth(3, 36 * 256);

                    var row = sheet.CreateRow(0);
                    row.Height = 20 * 20;

                    row.CreateCell(0).SetCellValue("序号");
                    row.CreateCell(1).SetCellValue("地层名称");
                    row.CreateCell(2).SetCellValue("地层材质");
                    row.CreateCell(3).SetCellValue("体积(m³)");

                    row.GetCell(0).CellStyle = centerStyle;
                    row.GetCell(1).CellStyle = centerStyle;
                    row.GetCell(2).CellStyle = centerStyle;
                    row.GetCell(3).CellStyle = centerStyle;



                    var quantitiesSummaries = SumEarthVolumns;
                    for (int j = 0; j < quantitiesSummaries.Count; j++)
                    {
                        try
                        {
                            var quantitiesSummary = quantitiesSummaries[j];
                            row = sheet.CreateRow(j + 1);
                            row.Height = 20 * 20;
                            row.CreateCell(0).SetCellValue(quantitiesSummary.OrderNumber);
                            row.CreateCell(1).SetCellValue(quantitiesSummary.EarthName);
                            row.CreateCell(2).SetCellValue(quantitiesSummary.EarthMaterial);
                            row.CreateCell(3).SetCellValue(quantitiesSummary.Volumn);


                            row.GetCell(0).CellStyle = centerStyle;
                            row.GetCell(1).CellStyle = centerStyle;
                            row.GetCell(2).CellStyle = centerStyle;
                            row.GetCell(3).CellStyle = centerStyle;

                        }
                        catch (Exception)
                        {
                        }
                    }


                    using (var fileStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
                    {
                        workbook.Write(fileStream);
                        fileStream.Close();
                    }
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                    return false;
                }

                return true;
            });
        }

    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Bhidi.Revit.CalculateEarthworkVolume.Model
{
    public class SumEarthVolumn
    {
        private string orderNumber;

        private string earthMaterial;

        private double volumn;

        public string OrderNumber { get => orderNumber; set => orderNumber = value; }
        public string EarthMaterial { get => earthMaterial; set => earthMaterial = value; }
        public double Volumn { get => volumn; set => volumn = value; }



    }
}

using Autodesk.Revit.DB;
using CC.Style;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Bhidi.Revit.CalculateEarthworkVolume.Views
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : CCWindow
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new ViewModel.MainViewModel();
        }
    }
}

体量与体量相交体积计算。通用 interSolid = BooleanOperationsUtils.ExecuteBooleanOperation(solid, massSolid, BooleanOperationsType.Intersect); 不行的话用 切片积分法对相交的Solid进行了体积试算 重要

相关推荐
范特西.i1 小时前
QT聊天项目(4)
开发语言·qt
lly2024061 小时前
PostgreSQL DELETE 操作详解
开发语言
C#程序员一枚1 小时前
大字段查询性能优化终极方案
sql·c#
今天你TLE了吗1 小时前
JVM学习笔记:第二章——类加载子系统
java·开发语言·jvm·笔记
AutumnorLiuu2 小时前
C++并发编程学习(四)——死锁及其预防
开发语言·c++·学习
_OP_CHEN2 小时前
【前端开发之JavaScript】(二)JS基础语法上篇:吃透变量 / 类型 / 输入输出
开发语言·javascript·html·ecmascript·前端开发·网页开发
Maguyusi2 小时前
go 批量生成 c++与lua的proto文件
开发语言·后端·golang·protobuf
万能的小裴同学2 小时前
饥荒Mod
java·开发语言·junit
foxsen_xia2 小时前
Kamailio通过Lua写路由
开发语言·lua·信息与通信