主頁 > 後端開發 > SpringBoot集成onlyoffice實作word檔案編輯保存

SpringBoot集成onlyoffice實作word檔案編輯保存

2022-09-26 07:00:19 後端開發

說明

onlyoffice為一款開源的office在線編輯組件,提供word/excel/ppt編輯保存操作

  • 以下操作均基于centos8系統,officeonly鏡像版本7.1.2.23
  • 鏡像下載地址:https://yunpan.360.cn/surl_y87CKKcPdY4 (提取碼:1f92)
  • 已破解20連接限制
  • 已匯入常用中文字體,修改了字號
  • 已取消上傳檔案大小的限制,修改為500M
  • 隱藏所有操作按鈕,隱藏onlyoffice圖示和名稱,只保基礎操作欄目
  • 僅用于word檔案和excel檔案編輯/保存/查看

Linux安裝

yum設定

  • 進入yum的repos目錄 cd /etc/yum.repos.d/
cd /etc/yum.repos.d/
  • 修改所有的CentOS檔案內容
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*

sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
  • 更新yum源為阿里鏡像
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo

yum clean all

yum makecache
  • yum安裝測驗是否可以yum安裝
yum install wget –y
  • 安裝依賴包
sudo yum install -y yum-utils device-mapper-persistent-data lvm2 

docker安裝

  • 設定鏡像源
sudo yum-config-manager --add-repo
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  • 安裝docker-ce社區版
sudo yum install docker-ce --allowerasing
  • 創建用戶組
建立 Docker 用戶組
sudo groupadd docker
添加當前用戶到 docker 組
sudo usermod -aG docker $USER
啟動docker
systemctl start docker.service
服務開機啟動
systemctl enable docker.service
  • 安裝docker圖形化管理頁面
docker volume create portainer_data

docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer

訪問http://localhost:9000/進行管理端初始化設定

onlyoffice部署

  • 上傳鏡像檔案到服務器
  • 載入鏡像
docker load < onlyoffice.tar
  • 查看鏡像
docker images
  • 啟動容器
sudo docker run --name=onlyoffice -i -t -d -p  8088:80 --restart=always 鏡像id

Windows安裝

  • 安裝VMWare虛擬機,安裝centos8系統,參照上述步驟
  • 網路配置成NAT模式,虛擬機進入centos系統后配置固定ip
  • NAT網卡設定埠轉發,轉發9000和8088埠,主機埠和虛擬埠一致

添加字體

  • 找到對應字體,如果是windows下的字體進入C:\Windows\Fonts 搜索
  • 安裝High-Logic FontCreator 運行Keygen.exe 點擊generate獲取激活碼
  • 工具下載:https://yunpan.360.cn/surl_y87CK8RNr8N (提取碼:7059)
  • 打開字體 font=>properties
  • 修改 font family 為custom 中對應的中文 ,匯出字體
  • 上傳修改后的字體到liunx檔案下 eg:/home/fonts/
  • 查看OnlyOffice容器id
docker ps
  • 進入OnlyOffice容器
docker exec -it 容器id /bin/bash
  • 洗掉字體快取
cd /var/www/onlyoffice/documentserver/fonts

rm -rf *
  • 復制字體到 /var/www/onlyoffice/documentserver/core-fonts 下
docker cp /home/fonts onlyoffice:/var/www/onlyoffice/documentserver/core-fonts
  • 進入onlyoffice容器執行重繪
/usr/bin/documentserver-generate-allfonts.sh
  • 瀏覽器清除快取重新重繪

對接業務系統

onlyfiice部署完畢后會有一個服務地址,例如 http://localhost:8088/

引入api.js

不能下載檔案本地參考,一定要在線參考

<script type="text/javascript" src="http://localhost:8088/web-apps/apps/api/documents/api.js"></script>

宣告dom

頁面添加一個div,用于渲染編輯器

<div id="placeholder"  style="width: 100%; height: 100%"></div>

頁面渲染

引數說明

key:對應檔案的一個標識,建議前端隨機生成,防止重復

url:打開檔案的地址,回傳流資料

fileType:檔案型別,例如:doc/docx

title:檔案名稱,例如:2022年作業方案.docx

model:打開模式,例如:edit(編輯模式)/view(閱讀模式)

callbackUrl:檔案修改后保存回呼地址

function initDoc(key, url, fileType, title, model, callbackUrl) {
                let config = {
                    "document": {
                        "documentType": "text",
                        "width": "100%", //打開視窗寬度
                        "height": "100%", //打開視窗高度
                        "fileType": fileType, //檔案型別
                        "key": key, //定義用于服務識別檔案的唯一檔案識別符號,每次編輯和保存檔案時,都必須重新生成密鑰,長度限制為128個符號,
                        "title": title, //為查看或編輯的檔案定義所需的檔案名,該檔案名也將在下載檔案時用作檔案名,長度限制為128個符號,
                        "url": url, //定義存盤原始查看或編輯的檔案的絕對URL
                        "info": {
                            "owner": "王重陽", //檔案創建者名稱
                            "sharingSettings": [ //檔案對應用戶的操作權限配置
                                {
                                    "permissions": "Full Access", // 完全操作權限-Full Access,只讀權限-Read Only 拒絕訪問-Deny Access
                                    "user": "林朝英" //有次權限的用戶
                                },
                                {
                                    "permissions": "Read Only",
                                    "user": "周伯通"
                                },
                            ],
                            "uploaded": "2010-07-07 3:46 PM" //檔案創建時間
                        },
                        //檔案權限引數
                        "permissions": {
                            "edit": true, //(檔案是否可以編輯,false時檔案不可編輯)
                            "fillForms": true, //定義是否能在檔案中填充表單
                            "print": true, //定義檔案是否能列印
                            "review": false, //第一是否顯示審閱檔案選單
                            "comment": true, //定義是否可以注釋檔案,如果注釋權限設定為“ true”,則檔案側欄將包含“注釋”選單選項;只有將mode引數設定為edit時才生效,默認值與edit引數的值一致,
                            "copy": true, //是否允許您將內容復制到剪貼板,默認值為true,
                            "download": true, //定義是否可以下載檔案或僅在線查看或編輯檔案,如果下載權限設定為“false”下載為選單選項將沒有,默認值為true,
                            "modifyContentControl": true, //定義是否可以更改內容控制元件設定,僅當mode引數設定為edit時,內容控制元件修改才可用于檔案編輯器,默認值為true,
                            "modifyFilter": true, //定義過濾器是否可以全域應用(true)影響所有其他用戶,或區域應用(false),即僅適用于當前用戶,如果將mode引數設定為edit,則過濾器修改僅對電子表格編輯器可用,默認值為true,
                        }
                    },
                    // type: "embedded",
                    //打開檔案型別
                    // text對應各種檔案型別(.doc, .docm, .docx, .dot, .dotm, .dotx, .epub, .fodt, .htm, .html, .mht, .odt, .ott, .pdf, .rtf, .txt, .djvu, .xps)
                    //spreadsheet對應表格型別(.csv, .fods, .ods, .ots, .xls, .xlsm, .xlsx, .xlt, .xltm, .xltx)
                    //presentation對應PPT型別(.fodp, .odp, .otp, .pot, .potm, .potx, .pps, .ppsm, .ppsx, .ppt, .pptm, .pptx)
                    "editorConfig": { //編輯配置
                        "createUrl": "http://docServer:port/url-to-create-document/", //指定創建檔案的頁面,添加該配置后檔案服務器插件才會顯示新建檔案按鈕
                        "mode": model, //檔案操作模式 view 視圖模式不可編輯  edit 編輯模式可編輯檔案
                        "callbackUrl": callbackUrl, //保存檔案時的回呼地址
                        "lang": "zh-CN", //語言環境
                        "customization": { //定制部分允許自定義編輯器界面,使其看起來像您的其他產品,并更改是否存在其他按鈕,鏈接,更改徽標和編輯者所有者詳細資訊,
                            "help": false, //定義是顯示還是隱藏“幫助”選單按鈕,默認值為true,
                            "hideRightMenu": false, //定義在第一次加載時是顯示還是隱藏右側選單,默認值為false,
                            "autosave": false, //定義是啟用還是禁用“自動保存”選單選項,請注意,如果您在選單中更改此選項,它將被保存到瀏覽器的localStorage中,默認值為true,
                            "forcesave": true, //定義保存按鈕是否顯示默認false
                            "chat": false, //定義“聊天”選單按鈕是顯示還是隱藏;請注意,如果您隱藏“聊天”按鈕,則相應的聊天功能也將被禁用,默認值為true,
                            "commentAuthorOnly": false, //定義用戶是否只能編輯和洗掉他的評論,默認值為false,
                            "comments": false, //定義是顯示還是隱藏“注釋”選單按鈕;請注意,如果您隱藏“評論”按鈕,則相應的評論功能將僅可用于查看,評論的添加和編輯將不可用,默認值為true,
                            "compactHeader": false, //定義是否將選單欄放在在徽標旁邊使界面更加緊湊默認false,
                            "compactToolbar": false, //定義顯示的頂部工具列型別是完整(false)還是緊湊true,默認值為false 多余選單將在右側折疊點擊顯示,
                            "compatibleFeatures": false, //定義僅與OOXML格式兼容的功能的使用,例如,不要在整個檔案上使用注釋,默認值為false,
                            "macros": false, //定義是否將運行檔案宏以及可用的宏設定,默認值為true,
                            "macrosMode": "warn", //定義是否將運行檔案宏,可以采用以下值: disable -根本不運行;enable -自動運行所有宏;warn -警告宏并請求允許運行,默認值為original,
                            "plugins": false, //定義是否將啟動插件并可用,默認值為true,
                            "showReviewChanges": false, //定義在加載編輯器時是否自動顯示或隱藏審閱更改面板,默認值為false,
                            "spellcheck": false, //定義在加載編輯器時是否自動打開或關閉拼寫檢查器,拼寫檢查器僅適用于檔案編輯器和演示文稿編輯器,默認值為true,
                            "toolbarNoTabs": false, //定義是突出顯示頂部工具列選項卡樣式,默認值為false,
                            "unit": "cm", //定義在標尺和對話框中使用的度量單位,可以采用以下值:cm -厘米,pt-點,inch -英寸,默認值為厘米(cm),
                            "zoom": 100, //定義以百分比為單位的檔案顯示縮放值,可以取大于0的值,對于文本檔案和演示文稿,可以將此引數設定為-1(使檔案適合頁面選項)或-2(使檔案頁面寬度適合編輯器頁面),默認值為100,
                            "customer": { //關于 檔案編輯器的顯示資訊
                                "address": "My City, 123a-45", //有權訪問編輯或編輯作者的公司或個人的郵政地址,
                                "info": "Some additional information", //有關您希望其他人認識的公司或個人的一些其他資訊,
                                "logo": "https://example.com/logo-big.png", //圖片徽標的路徑(此檔案沒有特別建議,但是如果使用透明背景的.png格式會更好),圖片必須具有以下尺寸:432x70,
                                "mail": "[email protected]", //有權訪問編輯者或編輯者的公司或個人的電子郵件地址
                                "name": "歐陽鋒", //該公司或個人的誰可以訪問編輯或編輯作者,名稱
                                "www": "example.com" //以上公司或個人的家庭網站地址,
                            },
                            "feedback": { //反饋配置資訊
                                "url": "https://example.com", //單擊“反饋和支持”選單按鈕時將打開的網站地址的絕對URL ,
                                "visible": false //顯示或隱藏“反饋和支持”選單按鈕,
                            },
                            "goback": { //定義“打開檔案位置”選單按鈕和右上角按鈕的設定,該物件具有以下引數:
                                "blank": true, //在新的瀏覽器選項卡/視窗(如果值設定為true)或當前選項卡(如果值設定為false)中打開網站,默認值為true,
                                "requestClose": false, //定義如果單擊“打開檔案位置”按鈕,則呼叫events.onRequestClose事件,而不是打開瀏覽器選項卡或視窗,默認值為false,
                                "text": "Open file location", //將在“打開檔案位置”選單按鈕和右上角按鈕(即,而不是“轉到檔案”)上顯示的文本,
                                "url": "https://example.com" //單擊“打開檔案位置”選單按鈕時將打開的網站地址的絕對URL ,
                            },
                            "logo": {
                                "image": "https://example.com/logo.png", //影像檔案的路徑,用于在普通作業模式下顯示(即,在所有編輯器的查看和編輯模式下),圖片必須具有以下尺寸:172x40,
                                "imageEmbedded": "https://example.com/logo_em.png", //用于以嵌入式模式顯示的影像檔案的路徑(請參閱config部分以了解如何定義嵌入式檔案型別),圖片必須具有以下尺寸:248x40,
                                "url": "https://www.baidu.com" //某人單擊徽標影像時將使用的絕對URL(可用于轉到您的網站等),保留為空字串或null以使徽標不可單擊,
                            },
                        },
                        "user": { //用戶資訊
                            "id": "admin", //用戶ID
                            "name": "操作員" //用戶全名稱
                        },
                        "embedded": { //Embedded部分僅適用于嵌入式檔案型別(請參閱config部分以了解如何定義嵌入式檔案型別),它允許更改設定,這些設定定義嵌入式模式下按鈕的行為,
                            "embedUrl": "https://example.com/embedded?doc=exampledocument1.docx", //定義檔案的絕對URL,以作為嵌入到網頁中的檔案的源檔案
                            "fullscreenUrl": "https://example.com/embedded?doc=exampledocument1.docx#fullscreen", //定義將以全屏模式打開的檔案的絕對URL,
                            "saveUrl": "https://example.com/download?doc=exampledocument1.docx", //定義允許將檔案保存到用戶個人計算機上的絕對URL,
                            "shareUrl": "https://example.com/view?doc=exampledocument1.docx", //定義允許其他用戶共享此檔案的絕對URL,
                            "toolbarDocked": "top" //定義嵌入式查看器工具列的位置,可以為top或bottom,
                        }
                    },

                    "events": { //事件配置
                        // onAppReady,//-將應用程式加載到瀏覽器時呼叫的函式,
                        // onCollaborativeChanges //-當檔案由其他用戶在嚴格共同編輯模式下共同編輯時呼叫的函式,
                        // onDocumentReady,//-將應用程式加載到瀏覽器時呼叫的函式,
                        // onDocumentStateChange,//-修改檔案時呼叫的函式,這就是所謂的使用引數:{真正的“資料”}在當前用戶編輯檔案以及與引數:{“資料”:假}在當前用戶的更改發送到檔案編輯服務,
                        // onDownloadAs,//-呼叫downloadAs方法時,使用指向已編輯檔案的絕對URL呼叫的函式,在data引數中發送要下載的檔案的絕對URL ,
                        // one rror,//-發生錯誤或其他特定事件時呼叫的函式,錯誤訊息在data引數中發送,
                        // onInfo,//-應用程式打開檔案時呼叫的函式,該模式在data.mode引數中發送,可以查看或編輯,
                        // onMetaChange,//-通過meta命令更改檔案的元資訊時呼叫的函式,檔案名稱通過data.title引數發送,
                        // onOutdatedVersion,//-使用舊的document.key值打開檔案進行編輯時,顯示錯誤后呼叫的函式,該值用于編輯先前的檔案版本并已成功保存,呼叫此事件時,必須使用新的document.key重新初始化編輯器,
                        // onReady,//-將應用程式加載到瀏覽器時呼叫的函式,自從5.0版本不推薦使用,請使用onAppReady代替
                        // onRequestClose,//-結束編輯器的作業并且必須關閉編輯器時呼叫的函式,
                        // onRequestCompareFile,//-用戶嘗試通過單擊“存盤中的檔案”按鈕來選擇要比較的檔案時呼叫的函式,要選擇要比較的檔案,必須呼叫setRevisedFile方法,如果未宣告該方法,則不會顯示“來自存盤的檔案”按鈕,
                        // onRequestCreateNew,//-用戶嘗試通過單擊“新建”按鈕來創建檔案時呼叫的函式,使用此方法代替createUrl欄位,如果未宣告該方法且未指定createUrl,則將不會顯示“創建新”按鈕,
                        // onRequestEditRights,//-用戶嘗試通過單擊“編輯檔案”按鈕嘗試將檔案從視圖切換到編輯模式時呼叫的函式,呼叫該函式時,必須在編輯模式下再次初始化編輯器,如果未宣告該方法,則不會顯示“編輯”按鈕,
                        // onRequestHistory,//-用戶嘗試通過單擊“版本歷史記錄”按鈕顯示檔案版本歷史記錄時呼叫的函式,要顯示檔案版本歷史,您必須呼叫refreshHistory方法,如果未宣告該方法和onRequestHistoryData方法,則不會顯示“版本歷史記錄”按鈕,
                        // onRequestHistoryClose,//-當用戶嘗試通過單擊“關閉歷史記錄”按鈕來查看檔案版本歷史記錄時,試圖呼叫該檔案時呼叫的函式,呼叫該函式時,必須在編輯模式下再次初始化編輯器,如果未宣告該方法,則不會顯示“關閉歷史記錄”按鈕,
                        // onRequestHistoryData,//-用戶嘗試單擊檔案版本歷史記錄中的特定檔案版本時呼叫的函式,
                        // onRequestInsertImage,//-用戶嘗試通過單擊“保存影像”按鈕插入影像時呼叫的函式,影像插入的型別在引數data.c中指定,
                        // onRequestRename,//-用戶嘗試通過單擊“重命名...”按鈕重命名檔案時呼叫的函式,
                        // onRequestRestore,//-用戶單擊版本歷史記錄中的“還原”按鈕來還原檔案版本時呼叫的函式,
                        // onRequestSaveAs,//-用戶嘗試通過單擊“另存為...”按鈕保存檔案時呼叫的函式,檔案的標題和要下載的檔案的絕對URL在data引數中發送,如果未宣告該方法,則不會顯示“另存為...”按鈕,
                        // onRequestSharingSettings,//-用戶單擊“更改訪問權限”按鈕來管理檔案訪問權限時呼叫的函式,必須呼叫setSharingSettings方法來更新有關允許與其他用戶共享檔案的設定的資訊,如果未宣告該方法,則不會顯示“更改訪問權限”按鈕,
                        // onRequestUsers,//-評論者可以選擇要在評論中提及的其他用戶時呼叫的函式,要設定用戶串列,必須呼叫setUsers方法,
                        // onWarning,//-發生警告時呼叫的函式,警告訊息在data引數中發送,
                        // "onDocumentStateChange": function() {
                        // }, //檔案改變后的回呼
                        //"onDocumentReady" : onDocumentReady, //檔案初始化準備好后的回呼
                    },
                };
                var docEditor = new DocsAPI.DocEditor("placeholder", config);
            }

資料介面

  • 下載檔案

回傳資料流即可,示例如下

    @GetMapping("/download")
    @ResponseBody
    public void download(@RequestParam("attguid") String attguid, HttpServletRequest request, HttpServletResponse response) throws Exception {
        AttachmentDO attachment = attachmentService.selectOne(attguid);
        String filePath = "";
        //云上傳的附件
        if (attachment.getVirtualpath().contains("ReadAlOSS")) {
            if (attachment.getCanedit() == null || attachment.getCanedit() == 20) {
                String fileurl = aliUtil.readOSSFile(attachment);
                if (!StringUtil.isEmpty(fileurl)) {
                    response.sendRedirect(fileurl);
                }
            } else if (attachment.getCanedit() == 30) {
                String fileurl = huaWeiUtil.readOBSFile(attachment);
                System.out.println(fileurl);
                if (!StringUtil.isEmpty(fileurl)) {
                    response.sendRedirect(fileurl);
                }
            } else if (attachment.getCanedit() == 40) {
                String fileurl = minioUtil.readMinioFile(attachment);
                System.out.println(fileurl);
                if (!StringUtil.isEmpty(fileurl)) {
                    response.sendRedirect(fileurl);
                }
            }
        }
        //本地檔案
        String configPath = frameConfig.getAttachPath();
        filePath = configPath + attachment.getVirtualpath();

        File file = new File(filePath);
        if (file.exists()) {
            String filename = attachment.getFilename();
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "utf-8"));
            response.setCharacterEncoding("utf-8");
            response.setContentLength((int) file.length());

            byte[] buff = new byte[(int) file.length()];
            BufferedInputStream bufferedInputStream = null;
            OutputStream outputStream = null;
            try {
                outputStream = response.getOutputStream();
                bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
                int i = 0;
                while ((i = bufferedInputStream.read(buff)) != -1) {
                    outputStream.write(buff, 0, i);
                    outputStream.flush();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {

                try {
                    bufferedInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
  • 保存檔案

決議傳遞的引數,獲取檔案url下載到本地后,進行自定義業務操作

@PostMapping("/save")
    @ResponseBody
    public void save(@RequestParam Map<String, String> map, HttpServletRequest request, HttpServletResponse response) {
        PrintWriter writer = null;
        String body = "";
        String attguid = request.getParameter("attguid");
        try {
            writer = response.getWriter();
            Scanner scanner = new Scanner(request.getInputStream());
            scanner.useDelimiter("\\A");
            body = scanner.hasNext() ? scanner.next() : "";
            scanner.close();
        } catch (Exception ex) {
            writer.write("get request.getInputStream error:" + ex.getMessage());
            return;
        }

        if (body.isEmpty()) {
            throw new CustomerRuntimeException("ONLYOFFICE回呼保存請求體未空");
        }

        JSONObject jsonObj = JSONObject.parseObject(body);
        int status = (Integer) jsonObj.get("status");
        int saved = 0;
        String key = jsonObj.get("key").toString();
        if (status == 2 || status == 3 || status == 6) //MustSave, Corrupted
        {
            String downloadUri = (String) jsonObj.get("url");
            System.out.println(downloadUri);
            try {
                String filePath = "tempfiles/onlyoffice/savedownload/";
                FileUtil.initfloderPath(filePath);
                String fileName = CommonUtil.getNewGuid();
                HttpUtil.downLoadFromUrl(downloadUri, filePath, fileName);
                attachLogic.updateAttachContent(attguid, FileUtil.getBytes(filePath + fileName));
            } catch (Exception ex) {
                saved = 1;
                ex.printStackTrace();
            }
        }
        writer.write("{\"error\":" + saved + "}");
    }

外部按鈕接入

以保存按鈕為例

獲取編輯器iframe按鈕中的slot-btn-dt-save節點元素,定位div下的button按鈕,進行js模擬點擊實作保存操作

通過監聽iframe的message來捕獲到保存結束頁面彈出自定義提示

上述操作因編輯器html頁面和onlyoffice服務存在跨域問題,需要配置nginx代理到統一ip埠下

  function HandleSave() {
        var frameDocument = document.getElementsByTagName("iframe")[0].contentDocument;
        frameDocument.getElementById("slot-btn-dt-save").getElementsByTagName("button")[0].click();
    }

    window.onmessage = function (event) {
        var data = https://www.cnblogs.com/yanpeng19940119/archive/2022/09/25/JSON.parse(event.data);
        if (data.event =="onDocumentStateChange" && data.data =https://www.cnblogs.com/yanpeng19940119/archive/2022/09/25/= false) {
            OpenSuccessMessage("保存成功")
        }
    }

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/509488.html

標籤:其他

上一篇:驅動開發:內核CR3切換讀寫記憶體

下一篇:二叉樹查找和洗掉指定結點

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more