19. 12. 13.

Javascript & JQuery 퀵 메뉴

간단하게 만들어본 제이쿼리 퀵메뉴
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.12.4.min.js"></script>
    <style>
        .quick { position:absolute; width: 150px; top:0; right:0; display: inline-block; transition-duration: 1s; margin-top:10em; margin-right:1em; }
        /* 스크롤바 박스 */
        .quick > div { background-color: #f1f1f1; border: 2px solid #ddd; border-radius: 0.5em;}
    </style>
    <script>
        // 스크롤을 만들기위해 body 를 키움 없애도 뎀
        $(function () { $("html,body").css("height", "10000px");});
        // 따라다니게 하기 위한 처리
        $(window).scroll(function (e) {
            $(".quick").css("top", $(this).scrollTop()+"px");
        });
    </script>
</head>
<body>
    <div class="quick">
        <div>
            <ul>
                <li><a>menu 1</a></li>
                <li><a>menu 2</a></li>
                <li><a>menu 3</a></li>
                <li><a>menu 4</a></li>
                <li><a>menu 5</a></li>
            </ul>
        </div>
    </div>
</body>
</html>


자바스크립트(Javascript)로 변경해 봄
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <style>
        .quick { position:absolute; width: 150px; top:0; right:0; display: inline-block; transition-duration: 1s; margin-top:10em; margin-right:1em; }
        /* 스크롤바 박스 */
        .quick > div { background-color: #f1f1f1; border: 2px solid #ddd; border-radius: 0.5em;}
    </style>
    <script>
        // 창크기 키워 스크롤 나오게 하기
        window.onload = function () {
            document.getElementsByTagName("body")[0].style.height = "10000px";
        }
        window.addEventListener('scroll', function (e) {
            document.querySelector(".quick").style.top = window.scrollY + "px"
        })
    </script>
</head>
<body>
    <div class="quick">
        <div>
            <ul>
                <li><a>menu 1</a></li>
                <li><a>menu 2</a></li>
                <li><a>menu 3</a></li>
                <li><a>menu 4</a></li>
                <li><a>menu 5</a></li>
            </ul>
        </div>
    </div>
</body>
</html>

19. 12. 5.

GCP PHP + MariaDB + Nginx + vsftpd 구성

1. 프로젝트 생성
- 프로젝트명 : server
- 프로젝트 선택 : 전체 -> server

2. VM인스턴스 생성
- 메뉴 -> VM인스턴스 -> 만들기
- 이름 : mysite
- 머신유형 : 초소형(공유 vCPU 1 개)
- 부팅 디스크 : 변경 -> OS이미지 -> CentOS 8
- http 트래픽허용 체크
- 만들기

3. VM 인스턴스 목록
- SSH 클릭(인증되며 까만창 뜸)

4. 프롬프트 창내의 명령실행
- 관리자 접속
sudo su -
- 업데이트 및 다운로드,압축풀기 설치
yum update -y
yum install -y wget unzip
- FTP 용 계정생성 및 비밀번호 생성
useradd myid
passwd myid
- 사이트 경로 생성 및 권한 추가
mkdir /home/myid/mysite
chmod +x /home/myid/mysite
- PHP + 모듈 설치
dnf install -y dnf-utils http://rpms.remirepo.net/enterprise/remi-release-8.rpm
dnf module list php
dnf module reset php
dnf module install -y php:remi-7.4
dnf install -y php php-fpm php-mysql php-gd php-common php-cli php-json php-opcache php-devel php-imagick php-mbstring php-mcrypt php-mysqlnd php-pear php-xml php-xmlrpc php-soap php-dba php-bcmath php-pdo php-ldap
- vi 편집기("insert 키" : 편집 및 수정, "Escape 키" : 보기모드, ":wq" : 저장, ":q" : 저장하지않고 닫기, ":/검색어" : 검색어 검색 )
- 편집기로 PHP 설정파일(/etc/php.ini) 설정 명령
vi /etc/php.ini
- php.ini 변경내용(검색해서 해당 값만 변경)
cgi.fix_pathinfo = 0
allow_url_fopen = Off
expose_php = Off
display_errors = Off
- 편집기로 php-fpm 설정파일(/etc/php-fpm.d/www.conf) 수정
vi /etc/php-fpm.d/www.conf
- www.conf 변경내용 1. apache를 myid로 교체(apache로 검색)
user = myid
group = myid
- www.conf 변경내용 2. 주석제거(nobody로 검색)
listen.owner = nobody
listen.group = nobody
- www.conf 변경내용 3. listen 의 /run/php-fpm/www.sock을 127.0.0.1:9000으로 수정
listen = 127.0.0.1:9000
- Nginx 설치
wget http://nginx.org/packages/mainline/centos/8/x86_64/RPMS/nginx-1.17.6-1.el8.ngx.x86_64.rpm
yum localinstall -y nginx-1.17.6-1.el8.ngx.x86_64.rpm
- Nginx 설정파일 수정
vi /etc/nginx/nginx.conf
- Nginx 설정파일 수정내용(http{}안에 추가)
server_tokens off;
- 방화벽 설정(http,https,ftp,database(MariaDB))
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --permanent --add-service=ftp
firewall-cmd --permanent --add-port=21/tcp
firewall-cmd --permanent --add-port=3306/tcp
firewall-cmd --reload
- Nginx 기본 설정 삭제
rm -f /etc/nginx/conf.d/default.conf
- Nginx 기본 설정 만들기
vi /etc/nginx/conf.d/default.conf
- Nginx 기본 설정 만들기 내용(아래내용을 복사, 붙여넣기)
server {
    listen       80;
    server_name  localhost;
    charset utf-8;
    root   /home/myid/mysite;
    #access_log  /var/log/nginx/host.access.log  main;
    location / {
        index index.php index.html index.htm;
    }
    error_page  404              /404.html;
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /home/myid/mysite;
    }
    location ~ \.php(?:$|/) {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}
- php-fpm, nginx 재시작
systemctl start php-fpm nginx
systemctl enable php-fpm nginx
systemctl reload nginx
- ftp 프로그램인 vsftpd 설치
dnf -y install vsftpd
mv /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf_orig
grep -v ^# /etc/vsftpd/vsftpd.conf_orig > /etc/vsftpd/vsftpd.conf
- vsftpd 설정파일 삭제
rm -f /etc/vsftpd/vsftpd.conf
- vsftpd 설정파일 생성
vi /etc/vsftpd/vsftpd.conf
- vsftpd 설정파일 내용입력
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=NO
listen_ipv6=YES
pam_service_name=vsftpd
userlist_enable=YES
pasv_enable=Yes
pasv_max_port=40000
pasv_min_port=40000
- SELinux 권한에서 차단되는 경우가 있으므로 처리
setenforce 0
- SELinux 권한에서 차단되는 경우가 있으므로 설정도 편집
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
- ftp 불가한 아이디 목록1에서 편집(root 제거)
vi /etc/vsftpd/ftpusers
- ftp 불가한 아이디 목록2에서 편집(root 제거)
vi /etc/vsftpd/user_list
- vsftpd 설정된 서비스로 재시작
systemctl start vsftpd
systemctl enable vsftpd
systemctl restart vsftpd
- ftp 접속권한 편집
chown myid:myid /home/myid/
chown myid:myid /home/myid/mysite/
chown nginx:nginx /home/myid/
chown nginx:nginx /home/myid/mysite/
chown -R myid:myid /home/myid/
chmod -Rf 775 /home/myid
- ftp 아이디 myid 접근권한 편집
vi /etc/passwd
- ftp 아이디 myid 접근권한 편집맨아래 추가
myid:x:1001:1002::/home/myid/mysite:/bin/bash
- MariaDB 설정 추가
yum search mariadb
- MariaDB 설치 및 서비스 추가
yum install -y mariadb-server
systemctl start mariadb
systemctl enable mariadb
- MariaDB root 루트 비밀번호 생성 및 설정(비밀번호,접속권한,test테이블등)
mysql_secure_installation
- 그냥 순서대로함...
"엔터"
y
password
password
y
n
y
y
- MariaDB 재시작
systemctl restart mariadb
- MariaDB 접속
mysql -u root -p
- MariaDB 패스워드 로그인후 원격접속 가능하도록 root에 권한 부여, 비밀번호 다시 부여 후 접속 종료
GRANT ALL PRIVILEGES ON *.* TO root@'%' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;
exit
5. Google Cloud Platform 메뉴에서 VPC네트워크 방화벽설정
- Google Cloud Platform 메뉴 -> 방화벽규칙 -> 만들기
- 이름 : mysite
- 대상 : 네트워크의 모든인스턴스
- 소스 IP 범위: 0.0.0.0/0
- 프로토콜 및 포트 : tcp 체크 -> 20-21,3306,40000
- 만들기
6. PHP MariaDB 접속 테스트 - index.php 생성
vi /home/myid/mysite/index.php
- index.php 내용
<?php
$conn=mysqli_connect('127.0.0.1', 'root', 'password');
if($conn) 
  echo "db연결성공";
else
  echo "db연결 실패"; 
?>
7. ssh 옆에 외부 아이피 클릭 및 확인
8. ftp는 fileziller 이용하거나 크롬 브라우저로 접속확인가능

19. 8. 12.

윈도우 보안 설정 관련 레지스트리 정리된 사이트

윈도우 보안 관련 레지스트리 정리된 사이트

https://admx.help/

처음엔 그냥 영어로 보는데 한국어로 설정된 윈도우라 찾기가 어려울 땐 일단 카테고리를 선택하고 맨뒤에

&Language=ko-kr

를 넣어주면됨.

ex) https://admx.help/?Category=Windows_10_2016&Language=ko-kr

19. 5. 16.

Javascript 페이지 스크롤상 위치 상단표시

간혹 블러그에 보이길래 그냥 만들어봄
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <style type="text/css">
        #scrollBars{ position:fixed; height:8px; background-color:red; width:0; left:0; top:0; transition-duration:0.3s;}
    </style>
    <script type="text/javascript">
        var barId = "scrollBars";
        window.onload = function () {
            // bar 개체생성
            var barElm = document.createElement("div");
            barElm.setAttribute("id", barId);
            // body 에 추가
            document.body.appendChild(barElm);
            // 문서의폭
            var bMax = document.body.clientWidth;
            // 문서의 높이
            var bH = document.body.clientHeight;
            // 화면의 높이
            var wH = window.innerHeight;
            // 초기 세팅
            document.getElementById(barId).setAttribute("style", "width:" + Math.floor(window.scrollY / (bH - wH) * 100) + "%");
            // 스크롤 이벤트 등록
            document.addEventListener("scroll", function (e) {
                // 스크롤이 이동할때마다 처리
                document.getElementById(barId).setAttribute("style", "width:" + Math.floor(window.scrollY / (bH - wH) * 100) + "%");
            }, true);
        }
    </script>
</head>
<body>
    <div style="width:100%; height:5000px;">이건그냥 스크롤용으로 만든 태그</div>
</body>
</html>

19. 4. 24.

Javascript 한화면 단위 Mouse Wheel 이동

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title>MouseWheel</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <style type="text/css">
        html,body{ margin:0; padding:0; width:100%; height:100%;}
        .box{ width:100%; height:100%; position:relative; color:#ffffff; font-size:24pt;}
    </style>
    <script type="text/javascript">
        // 적용할 클래스명
        var className = "box";
        // 지금의 스크롤 위치를 담을 변수
        var currentScroll = 0;
        // 에니메이션 효과를 주기위한 function 명 선언
        var tim;
        window.onload = function () {
            /* Div Class 명 */
            // box클래스 추출
            var elm = document.getElementsByClassName(className);
            // box클래스 개수만큼 실행
            for (var i = 0; i < elm.length; i++) {
                // box 에 각각 마우스 휠 감지
                // 휠감지
                elm[i].addEventListener("mousewheel", MouseWheelHandler, false);
                // firefox 용 휠처리
                elm[i].addEventListener("DOMMouseScroll", MouseWheelHandler, true);
            }
        }
        function MouseWheelHandler(e) {
            // 스크롤 취소시킴(이걸 안할경우 도중에 명령을 받아 화면이 덜덜 거릴수 있음)
            e.preventDefault();
            // 휠값처리
            var delta = 0;
            if (!event) event = window.event;
            if (event.wheelDelta) {
                delta = event.wheelDelta / 120;
                if (window.opera) delta = -delta;
            }
            else if (event.detail)
                delta = -event.detail / 3;

            // 여러개일경우 다른 selector 을 확인하기위한 상위 dom 으로 이동
            var p = e.target.parentElement;
            // 몇번째 dom 인지 저장
            var index = Array.prototype.indexOf.call(p.children, e.target);
            // 같은 위치의 돔목록 을 저장
            var elmArr = e.target.parentElement.children;
            // 지금의 스크롤 위치 저장
            currentScroll = document.documentElement.scrollTop || document.body.scrollTop;
            // 다음위치의 좌표(기본이므로 현재의 Y 좌표 저장)
            var NextTarget = currentScroll;
            // 마우스휠 위로
            if (delta > 0) {
                // 맨처음 지점 제외
                if (index > 0) {
                    // 이전 dom 의 index 번호
                    var no = (index - 1);
                    // 좌표위치 저장
                    NextTarget = elmArr[no].offsetTop;
                }
            }
            // 마우스휠 아래로
            else if (delta < 0)
            {
                // 맨마지막 지점 제외
                if (index < elmArr.length - 1) {
                    // 다음 dom 의 index 번호
                    var no = (index + 1);
                    // 좌표위치 저장
                    NextTarget = elmArr[no].offsetTop;
                }
            }
            // 애니메이션
            // 필요없으면 바로 window.scrollTo(0, NextTarget);
            // 에니메이션 초기화
            clearInterval(tim);
            // 애니메이션 실행
            tim = setInterval(tran, 1);
            // 애니메이션 function
            function tran() {
                // 이동속도 숫자가 작아질수록 느려짐
                var speed = 5;
                // 현재 스크롤과 이동후 스크롤이 같으면 정지시킨다 
                if (currentScroll == NextTarget) {
                    clearInterval(tran);
                } else {
                    // 스크롤을 위로 올릴 경우
                    if (currentScroll - speed > NextTarget)
                    {
                        currentScroll -= speed;
                    }
                    // 스크롤을 내일 경우
                    else if (currentScroll + speed < NextTarget)
                    {
                        currentScroll += speed;
                    }
                    // 스크롤이 속도로 지정된 변수보다 작을 경우 강제적으로 맞춰준다
                    else
                    {
                        currentScroll = NextTarget;
                    }
                    // 스크롤위치 변경
                    window.scrollTo(0, currentScroll);
                }
            }

        }
    </script>
</head>
<body>
    <div class="box" style="background-color:red;">1</div>
    <div class="box" style="background-color:orange;">2</div>
    <div class="box" style="background-color:yellow;">3</div>
    <div class="box" style="background-color:green;">4</div>
    <div class="box" style="background-color:blue;">5</div>
    <div class="box" style="background-color:indigo;">6</div>
    <div class="box" style="background-color:violet;">7</div>
</body>
</html>

JQuery 한화면 단위 Mouse Wheel 이동 를 참고해서 그냥 Javascript 로...

19. 4. 8.

GCP PHP + MariaDB + Nginx + vsftpd 구성

1. 프로젝트 생성
- 프로젝트명 : server
- 프로젝트 선택 : 전체 -> server

2. VM인스턴스 생성
- 메뉴 -> VM인스턴스 -> 만들기
- 이름 : mysite
- 머신유형 : 초소형(공유 vCPU 1 개)
- 부팅 디스크 : 변경 -> OS이미지 -> CentOS 7
- http 트래픽허용 체크
- 만들기

3. VM 인스턴스 목록
- SSH 클릭(인증되며 까만창 뜸)

4. 프롬프트 창내의 명령실행
- 업데이트 및 다운로드,압축풀기 설치
sudo yum update -y
sudo yum install -y wget unzip
- FTP 용 계정생성 및 비밀번호 생성
sudo useradd myid
sudo passwd myid
- 사이트 경로 생성 및 권한 추가
sudo mkdir /home/myid/mysite
sudo chmod +x /home/myid/mysite
- PHP + 모듈 설치
sudo yum install -y epel-release
sudo rpm -ivh http://rpms.remirepo.net/enterprise/remi-release-7.rpm
sudo yum --enablerepo=remi update remi-release
sudo yum --enablerepo=remi-php73 install -y php php-fpm php-mysql php-gd php-common php-cli php-json php-opcache php-devel php-imagick php-mbstring php-mcrypt php-mysqlnd php-pear php-xml php-xmlrpc php-soap php-dba php-bcmath php-pdo php-ldap
- vi 편집기("insert 키" : 편집 및 수정, "Escape 키" : 보기모드, ":wq" : 저장, ":q" : 저장하지않고 닫기, ":/검색어" : 검색어 검색 )
- 편집기로 PHP 설정파일(/etc/php.ini) 설정 명령
sudo vi /etc/php.ini
- php.ini 변경내용(검색해서 해당 값만 변경)
cgi.fix_pathinfo = 0
allow_url_fopen = Off
expose_php = Off
display_errors = Off
- 편집기로 php-fpm 설정파일(/etc/php-fpm.d/www.conf) 수정
sudo vi /etc/php-fpm.d/www.conf
- www.conf 변경내용 1. apache를 myid로 교체(apache로 검색)
user = myid
group = myid
- www.conf 변경내용 2. 주석제거(nobody로 검색)
listen.owner = nobody
listen.group = nobody
- Nginx 설정파일 생성
sudo vi /etc/yum.repos.d/nginx.repo
- nginx.repo 내용 입력(신규생성)
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
- Nginx 설치
sudo yum install -y nginx
- Nginx 설정파일 수정
sudo vi /etc/nginx/nginx.conf
- Nginx 설정파일 수정내용(http{}안에 추가)
server_tokens off;
- 방화벽 설정(http,https,ftp,database(MariaDB))
sudo firewall-cmd --permanent --zone=public --add-service=http
sudo firewall-cmd --permanent --zone=public --add-service=https
sudo firewall-cmd --permanent --add-service=ftp
sudo firewall-cmd --permanent --add-port=21/tcp
sudo firewall-cmd --permanent --add-port=3306/tcp
sudo firewall-cmd --reload
- Nginx 기본 설정 삭제
sudo rm /etc/nginx/conf.d/default.conf
- Nginx 기본 설정 만들기
sudo vi /etc/nginx/conf.d/default.conf
- Nginx 기본 설정 만들기 내용(아래내용을 복사, 붙여넣기)
server {
    listen       80;
    server_name  localhost;
    charset utf-8;
    root   /home/myid/mysite;
    #access_log  /var/log/nginx/host.access.log  main;
    location / {
        index index.php index.html index.htm;
    }
    error_page  404              /404.html;
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /home/myid/mysite;
    }
    location ~ \.php(?:$|/) {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}
- php-fpm, nginx 재시작
sudo systemctl start php-fpm
sudo systemctl enable php-fpm
sudo systemctl start nginx
sudo systemctl enable nginx
sudo systemctl reload nginx
- ftp 프로그램인 vsftpd 설치
sudo yum -y install vsftpd
- vsftpd 설정파일 삭제
sudo rm /etc/vsftpd/vsftpd.conf
- vsftpd 설정파일 생성
sudo vi /etc/vsftpd/vsftpd.conf
- vsftpd 설정파일 내용입력
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_file=/var/log/xferlog
xferlog_std_format=YES
chroot_local_user=YES
listen=YES
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
allow_writeable_chroot=yes
pasv_enable=Yes
pasv_max_port=40000
pasv_min_port=40000
- SELinux 권한에서 차단되는 경우가 있으므로 처리
sudo setenforce 0
- SELinux 권한에서 차단되는 경우가 있으므로 설정도 편집
sudo vi /etc/selinux/config
- SELinux 권한에서 차단되는 경우가 있으므로 설정도 편집(내용수정 disabled)
SELINUX=disabled
- vsftpd 설정된 서비스로 재시작
sudo systemctl enable vsftpd
sudo systemctl restart vsftpd
- ftp 불가한 아이디 목록1에서 편집(root 제거)
sudo vi /etc/vsftpd/ftpusers
- ftp 불가한 아이디 목록2에서 편집(root 제거)
sudo vi /etc/vsftpd/user_list
- ftp 접속권한 편집
sudo chown myid:myid /home/myid/mysite/
sudo chmod 555 /home/myid
sudo chmod 777 /home/myid/mysite
- ftp 아이디 myid 접근권한 편집
sudo vi /etc/passwd
- ftp 아이디 myid 접근권한 편집맨아래 추가
myid:x:1001:1002::/home/myid/mysite:
myid:x:1001:1002::/home/myid/mysite:/bin/bash
- MariaDB 설정 추가
sudo vi /etc/yum.repos.d/MariaDB.repo
- MariaDB 설정 추가(새로생성)
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.3/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
- MariaDB 설치 및 서비스 추가
sudo yum install -y MariaDB-client MariaDB-server
sudo systemctl start mariadb
sudo systemctl enable mariadb
- MariaDB root 루트 비밀번호 생성 및 설정(비밀번호,접속권한,test테이블등)
sudo mysql_secure_installation
- 그냥 순서대로함...
password
password
y
n
y
y
- MariaDB 재시작
sudo systemctl restart mariadb
- MariaDB 접속
sudo mysql -u root -p
- MariaDB 패스워드 로그인후 원격접속 가능하도록 root에 권한 부여, 비밀번호 다시 부여 후 접속 종료
GRANT ALL PRIVILEGES ON *.* TO root@'%' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;
exit
5. Google Cloud Platform 메뉴에서 VPC네트워크 방화벽설정
- Google Cloud Platform 메뉴 -> 방화벽규칙 -> 만들기
- 이름 : mysite
- 대상 : 네트워크의 모든인스턴스
- 소스 IP 범위: 0.0.0.0/0
- 프로토콜 및 포트 : tcp 체크 -> 20-21,3306,40000
- 만들기
6. PHP MariaDB 접속 테스트 - index.php 생성
sudo vi /home/myid/mysite/index.php
- index.php 내용
<?php
$conn=mysqli_connect('127.0.0.1', 'root', 'password');
if($conn) 
  echo "db연결성공";
else
  echo "db연결 실패"; 
?>
7. ssh 옆에 외부 아이피 클릭 및 확인
8. ftp는 fileziller 이용하거나 크롬 브라우저로 접속확인가능

19. 4. 4.

C#으로 MYSQL 연동

C# 에서 MySql을 연동하려면 사전 준비가 필요.

기준 : 비주얼스튜디오
1. 프로젝트 생성할 때 프레임워크를 4.5.2로 생성
2. 솔루션 탐색기의 프로젝트명에서 우클릭
3. NuGet 패키지 관리
4. MySql.Data 설치(8.0.15 버전으로 설치함)

insert,update,delete
using MySql.Data.MySqlClient;

namespace MySql
{
    class Program
    {
        static void Main(string[] args)
        {
            // Sql 연결정보(서버:127.0.0.1, 아이디:sa, 비밀번호 : password, db : member)
            string connectionString = "server = 127.0.0.1; uid = sa; pwd = password; database = member;";
            // Sql 새연결정보 생성
            MySqlConnection sqlConn = new MySqlConnection(connectionString);
            MySqlCommand sqlComm = new MySqlCommand();
            sqlComm.Connection = sqlConn;
            sqlComm.CommandText = "insert into tbl_member (id,name,addr) values ('abc','홍길동','서울');";
            //sqlComm.CommandText = "update tbl_member set addr='서울' where id='abc' and name='홍길동';";
            //sqlComm.CommandText = "delete tbl_member where id='abc' and name='홍길동' and addr='서울';";
            sqlConn.Open();
            sqlComm.ExecuteNonQuery();
            sqlConn.Close();
        }
    }
}


select
using MySql.Data.MySqlClient;
using System;

namespace MySql
{
    class Program
    {
        static void Main(string[] args)
        {
            string connectionString = "server = 127.0.0.1,3535; uid = sa; pwd = password; database = member;";
            // Sql 새연결정보 생성
            MySqlConnection sqlConn = new MySqlConnection(connectionString);
            MySqlCommand sqlComm = new MySqlCommand();
            sqlComm.Connection = sqlConn;
            sqlComm.CommandText = "select id,addr from tbl_member where name='홍길동' order by id asc limit 10";
            sqlConn.Open();
            using (MySqlDataReader SqlRs = sqlComm.ExecuteReader())
            {
                Console.WriteLine("ID \t \t | Address");
                while (SqlRs.Read())
                {
                    Console.WriteLine(string.Format("{0} \t \t | {1}", SqlRs[0].ToString(), SqlRs[1].ToString()));
                }
            }
            sqlConn.Close();
        }
    }
}

이미지 파일 업로드 전 미리보기

<!DOCTYPE html> 
<html lang="ko"> 
<head> 
<meta charset="utf-8"/>
<title>업로드 미리보기(추가버전)</title>
<style>
    ul,li{ margin: 0; padding: 0;}
    li{ list-style: none; width: 100%; display: inline-block; margin: 0.3em 0;}
    .preview{ display: inline-block; width: 82px; height: 82px; float: left;}
    .imgUpBtn{ display: inline-block; padding: 1.9em 2em; background-color:cornflowerblue; color: #fff; font-size: 16px;  font-weight: 700; border: 0;}
    .ImgRemoveBtn{ display: inline-block; padding: 1.9em 2em; color: #fff; background-color: #555;font-size: 16px; font-weight: 700;}
    #ImgAddBtn{ padding: 1.9em 2em; color: #fff; background-color:coral; font-weight: 700;}
</style>
<script> 
// 미리보기 목록 추가 
function fileinputAdd(){ 
    // 미리보기 리스트 추가 
    var li = "<img class=\"preview\" alt=\"\" />" 
            + "<button class=\"imgUpBtn\">이미지 업로드</button>" 
            + "<a class=\"ImgRemoveBtn\">삭제</a>"; 
    var ul = document.getElementById("image-list"); 
    ul.innerHTML += "<li>"+li+"</li>"; 
    // 인풋 파일 생성 
    var fileinput = document.createElement("INPUT"); 
    fileinput.setAttribute("type", "file"); 
    fileinput.setAttribute("class", "files"); 
    fileinput.setAttribute("name", "files[]"); 
    fileinput.setAttribute("accept", "image/jpeg, image/png"); 
    fileinput.setAttribute("style", "display:none;"); 
    document.body.appendChild(fileinput); 
    // 삭제도 있어야될것 같아서 넣어봄 
    var removeBtn = document.getElementsByClassName("ImgRemoveBtn"); 
    for(var i = 0; i < removeBtn.length; i++){ 
          removeBtn[i].setAttribute("onclick","fileinputRemove("+i+");"); 
   } 
   // 새로 생성되면서 파일 미리보기 다시 로드 
   previewInputReload(); 
   // 이미지 업로드 버튼 기능 다시 로드 
   fileimgUpBtnReload(); 
} 
// 미리보기 개별 삭제 
function fileinputRemove(index){ 
    var li = document.querySelectorAll('#image-list li')[index]; 
    var input = document.getElementsByClassName('files')[index]; 
    var removeBtn = document.getElementsByClassName("ImgRemoveBtn")[index]; 
    if(li != undefined){ 
          input.remove(); 
          li.remove(); 
          removeBtn.remove(); 
          li = document.querySelectorAll('#image-list li'); 
          for(var i = 0; i < li.length; i++){ 
                var removeBtn = document.getElementsByClassName("ImgRemoveBtn")[i]; 
                removeBtn.setAttribute("onclick","fileinputRemove("+i+");"); 
         } 
  } 
  // 삭제되면되면 파일 미리보기 다시 로드 
  previewInputReload(); 
  // 삭제후 이미지 업로드 버튼 기능 다시 로드 
  fileimgUpBtnReload(); 
} 
// 파일 업로드기능 function 연결하는 부분 
function fileimgUpBtnReload(){ 
    var uploadBtn = document.getElementsByClassName('imgUpBtn'); 
    for(var i = 0; i <uploadBtn.length; i++){ 
          uploadBtn[i].setAttribute("onclick","uploadFile("+i+");"); 
   } 
} 
// 이미지 업로드 버튼 눌를때 해당 파일인풋 대신 클릭 
function uploadFile(index){ 
    document.getElementsByClassName("files")[index].click(); 
} 
// 이미지 미리보기 관련 다시 로드 
function previewInputReload(){ 
    var input = document.getElementsByClassName('files'); 
    for(var i=0; i< input.length;i++){ 
          input[i].setAttribute("onchange","document.getElementsByClassName('preview')["+i+"].src=window.URL.createObjectURL(this.files[0])"); 
   } 
} 
// window 로드시 
window.onload = function(){ 
    // image-list 에 기본적으로 파일 업로드 하나는 넣어줌.. 
    fileinputAdd(); 
    var AddBtn = document.getElementById("ImgAddBtn"); 
    // 파일 추가 클릭 이벤트 생성 
    AddBtn.addEventListener("click", function(){ 
          fileinputAdd(); 
   },false); 
} 
</script> 
</head> 
<body> 
    <button id="ImgAddBtn">파일추가</button> 
    <ul id="image-list"></ul> 
</body> 
</html> 

<!DOCTYPE html> 
<html lang="ko"> 
<head> 
<meta charset="utf-8"/>
<title>업로드 미리보기(단딜(multiple) 버전)</title>
<style>
    #image-list > img{ width: 82px; height: 82px; margin: 1px; display: inline-block;}
    #imgUpBtn{ padding: 1.9em 2em; color: #fff; background-color:coral; font-weight: 700;}
</style>
<script>
// window 로드시 
window.onload = function(){ 
    var UpBtn = document.getElementById("imgUpBtn"); 
    // 파일 추가 클릭 이벤트 생성 
    UpBtn.addEventListener("click", function(){ 
        var fileinput = document.createElement("INPUT"); 
        fileinput.setAttribute("type", "file"); 
        fileinput.setAttribute("class", "files"); 
        fileinput.setAttribute("name", "files[]");
        fileinput.setAttribute("id", "imgUpInput");
        fileinput.setAttribute("multiple", "multiple");
        fileinput.setAttribute("accept", "image/jpeg, image/png"); 
        fileinput.setAttribute("style", "display:none;");
        // 파일 변동시 처리
        fileinput.setAttribute("onchange","previewImages(this.files);");
        document.body.appendChild(fileinput);
        // input file 를 눌러줌
        document.getElementById("imgUpInput").click();
    },false); 
} 
function previewImages(obj){
    for(var i = 0; i < obj.length; i++){
        var img = document.createElement("img");
        img.setAttribute("src", window.URL.createObjectURL(obj[i]));
        var list = document.getElementById("image-list");
        list.appendChild(img);
    }
}
</script> 
</head> 
<body>
    <button id="imgUpBtn">이미지 업로드</button>
    <div id="image-list"></div> 
</body> 
</html> 

19. 2. 27.

CKEditor 4 여러 파일 업로드(JQuery 필요) 플러그인

CK Editor 4 파일 업로드 plugin

아이콘(png) 파일 : /ckeditor/4.5.2/plugins/fileupload/icons/fileupload.png


플러그인(js) 경로 : /ckeditor/4.5.2/plugins/fileupload/plugin.js

// plugin.js 파일 소스
CKEDITOR.plugins.add('fileupload', {
    icons: 'fileupload',
    init: function (editor) {
        editor.addCommand('FileUpload', {
            exec: function (editor) {
                var x = document.createElement("INPUT");
                x.setAttribute("type", "file");
                x.setAttribute("name", "file");
                x.setAttribute("multiple", "multiple"); // 여러파일 가능하도록 속성 처리
                x.setAttribute("id", "ckfile");
                x.setAttribute("style", "display:none;");

                if($("#ckfile").length==0)
                    $("body").append(x);
                
                $("#ckfile").on("change",function(){
                    var ofw = $("body").css("overflow");
                    var html = [];
                    var formData = new FormData();
                    for (var i = 0; i < x.files.length; i++) {
                        formData.append("fileObj"+i, x.files[i]);
                    }
                    $.ajax({
                        url: '/upload/',
                        data: formData,
                        type: 'POST',
                        processData: false,
                        contentType: false,
                        beforeSend: function () {
                            $("body").css("overflow", "hidden");
                            $("body").append("<ul id=\"editorLoadingBar\" class=\"LoadingBar\"><li><div class=\"loader\">Loading...</div></li></ul>");
                        },
                        success: function (data) {
                            var txt = data.replace(/<(\/script|script)([^>]*)>/gi, "");
                            if (txt.indexOf("업로드성공") == -1) {
                                alert("파일을 업로드 하는데 실패하였습니다.");
                                return;
                            }
                            var patten1 = /\(.+?\)/g;
                            var txtString = txt.match(patten1)[0].replace(/\(/gi, '[').replace(/\)/gi, ']').replace(/\'/gi, '"');
                            var arr = JSON.parse(txtString);
                            if (arr.length == 4) {
                                var fileArr1 = arr[1].split(",");
                                var fileArr2 = arr[3].split(",");
                                if (fileArr1.length == fileArr2.length) {
                                    for (var i = 0; i < fileArr1.length; i++) {
                                        var src = fileArr1[i];
                                        var dot = src.lastIndexOf('.');
                                        var ext = src.substring(dot + 1, src.length).toLowerCase();;
                                        if (("jpg|jpeg|png|gif|bmp").indexOf(ext) > -1) {
                                            html.push("<img src=\"" + src + "\" alt=\""+fileArr2[i]+"\" /><br/>");
                                        } else if (("mp4").indexOf(ext) > -1) {
                                            html.push("<video controls=\"controls\" src=\"" + src + "\" type=\"video/mp4\"> </video><br/>");
                                        } else if (("mp3").indexOf(ext) > -1) {
                                            html.push("<audio controls=\"controls\" src=\"" + src + "\"></audio><br/>");
                                        } else if (("zip|pdf|hwp|doc|docx|xls|xlsx|ppt|pptx|psd").indexOf(ext) > -1) {
                                            html.push("<a href=\"/download/?path=" + escape(src).replace(/\+/gi, '%2B')
                                                + "&name=" + escape(fileArr2[i]).replace(/\+/gi, '%2B') + "\" target=\"_blank\">" + fileArr2[i] + "</a><br/>");
                                        }
                                    }
                                }
                            }
                        }, complete: function () {
                            $("body").css("overflow", ofw);
                            $("#editorLoadingBar").remove();
                            editor.insertHtml(html.join(''));
                        }
                    });
                });
                $("#ckfile").click();
            }
        });
        editor.ui.addButton('FileUpload', {
            label: '파일첨부',
            command: 'FileUpload',
            toolbar: 'insert'
        });
    }
});



업로드되는 파일 처리 : /upload/

단일 파일

<script type="text/javascript">window.parent.CKEDITOR.tools.callFunction('', '/파일경로/파일명', '업로드성공','파일명');</script>



3개파일의 경우

<script type="text/javascript">window.parent.CKEDITOR.tools.callFunction('', '/저장경로/저장명1,/저장경로/저장명2,/저장경로/저장명3', '업로드성공','파일명1,파일명2,파일명3,');</script>


설정(js) 파일 : /ckeditor/4.5.2/config.js

CKEDITOR.editorConfig = function( config ) {
    config.extraPlugins = "fileupload"; // 플러그인이 하나일 경우
    //config.extraPlugins = "youtube,fileupload"; // 플러그인이 여러개일 경우
}

19. 1. 28.

HTML을 PDF로 저장(C#, VB)

Visual Studio 의 솔루션 탐색기에서 우클릭

Nuget 패키지 관리 -> 찾아보기 -> NReco.PdfGenerator -> 설치


C#
using System.IO;
using System.Text;

namespace HtmlToPdf
{
    class Program
    {
        static void Main(string[] args)
        {
            StringBuilder saveHtml = new StringBuilder();
            saveHtml.Append("<!DOCTYPE html>");
            saveHtml.Append("<html lang=\"ko\">");
            saveHtml.Append("<head>");
            saveHtml.Append("<meta charset=\"utf-8\" />");
            saveHtml.Append("<title>Html을 PDF로</title>");
            saveHtml.Append("</head>");
            saveHtml.Append("<body>");
            saveHtml.Append("<h1>Html을 PDF로</h1><p>좋은하루입니다.</p>");
            saveHtml.Append("</body>");
            saveHtml.Append("</html>");

            // NReco 호출
            var converter = new NReco.PdfGenerator.HtmlToPdfConverter();
            // 저장할 파일명
            string pdfFile = @"d:\test.pdf";
            // 파일이 있을경우 삭제
            if (File.Exists(pdfFile))
            {
                File.Delete(pdfFile);
            }
            // saveHtml을 pdf byte 형식으로 반환
            byte[] f = converter.GeneratePdf(saveHtml.ToString());
            // 파일을 저장
            File.WriteAllBytes(pdfFile, f);
        }
    }
}


VB
Imports System.IO
Imports System.Text

Module Module1
    Sub Main()
        Dim saveHtml As StringBuilder = New StringBuilder
        saveHtml.Append("<!DOCTYPE html>")
        saveHtml.Append("<html lang=""ko"">")
        saveHtml.Append("<head>")
        saveHtml.Append("<meta charset=""utf-8"" />")
        saveHtml.Append("<title>Html을 PDF로</title>")
        saveHtml.Append("</head>")
        saveHtml.Append("<body>")
        saveHtml.Append("<h1>Html을 PDF로</h1><p>좋은하루입니다.</p>")
        saveHtml.Append("</body>")
        saveHtml.Append("</html>")

        ' NReco 호출
        Dim Converter = New NReco.PdfGenerator.HtmlToPdfConverter
        ' 저장할 파일명
        Dim pdfFile As String = "d:\test.pdf"
        ' 파일이 있을경우 삭제
        If File.Exists(pdfFile) Then
            File.Delete(pdfFile)
        End If

        ' saveHtml을 pdf byte 형식으로 반환
        Dim f As Byte() = Converter.GeneratePdf(saveHtml.ToString())
        ' 파일을 저장
        File.WriteAllBytes(pdfFile, f)
    End Sub
End Module

19. 1. 26.

C# 에서 엑셀(Xlsx) 저장

Visual Studio 의 솔루션 탐색기에서 우클릭

Nuget 패키지 관리 -> 찾아보기 -> EPPlus -> 설치


using OfficeOpenXml;
using System;
using System.Collections.Generic;
using System.IO;

namespace XlsxSaveProgram
{
    class Program
    {
        static void Main(string[] args)
        {
            // 저장파일명
            string xlsxfile = string.Format("Test{0}.xlsx", DateTime.Now.ToString("yyyyMMddHHmmss"));

            // 기존파일있을경우 삭제
            FileInfo excelFile = new FileInfo(xlsxfile);
            if (excelFile.Exists) { excelFile.Delete(); }

            // 조회기간
            DateTime date1 = DateTime.Now.AddDays(-7);
            DateTime date2 = DateTime.Now.AddDays(-1);

            // 시트가 여러개일 경우
            string[] sheets = new string[] { "시트1", "시트2", "시트3" };
            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
            // 패키지가 이용가능하다면
            using (ExcelPackage excel = new ExcelPackage())
            {
                // 시트 개수만큼 반복
                for (var i = 0; i < sheets.Length; i++)
                {
                    // 시트 추가
                    excel.Workbook.Worksheets.Add(sheets[i]);
                    // 상단 고정내용 처리
                    List<object[]> dataRow = new List<object[]>()
                    {
                        new string[] { sheets[i] },
                        new string[] { string.Format("{0} ~ {1}", date1.ToString("yyyy.MM.dd"), date2.ToString("yyyy.MM.dd")) },
                        new string[] { "컬럼1","컬럼2","컬럼3","컬럼4","컬럼5","컬럼6" }
                    };

                    // 몇줄인지 cnt에저장
                    decimal cnt = 0;
                    dataRow.Add(new object[] { "필드1_1", "필드2_1", "필드3_1", "필드4_1", "필드5_1", "필드6_1" });
                    dataRow.Add(new object[] { "필드1_2", "필드2_2", "필드3_2", "필드4_2", "필드5_2", "필드6_2" });
                    // 2줄만 추가했으므로
                    cnt = 2;
                    
                    string headerRange = "A1:" + Char.ConvertFromUtf32(dataRow[0].Length + 64) + "1";

                    // 시트선택
                    var worksheet = excel.Workbook.Worksheets[sheets[i]];

                    // 워크시트에 DataRow 를 불러옴
                    worksheet.Cells[headerRange].LoadFromArrays(dataRow);

                    // 스타일 지정
                    worksheet.Column(1).Width = 18;
                    worksheet.Column(2).Width = 26;
                    worksheet.Column(3).Width = 26;
                    worksheet.Column(4).Width = 16;
                    worksheet.Column(5).Width = 16;
                    worksheet.Column(6).Width = 21;

                    worksheet.Column(1).Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center;
                    worksheet.Column(2).Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center;
                    worksheet.Column(3).Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center;
                    worksheet.Column(4).Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center;
                    worksheet.Column(5).Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center;
                    worksheet.Column(6).Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center;

                    worksheet.Column(1).Style.Font.SetFromFont(new System.Drawing.Font("나눔고딕", 10));
                    worksheet.Column(2).Style.Font.SetFromFont(new System.Drawing.Font("나눔고딕", 10));
                    worksheet.Column(3).Style.Font.SetFromFont(new System.Drawing.Font("나눔고딕", 10));
                    worksheet.Column(4).Style.Font.SetFromFont(new System.Drawing.Font("나눔고딕", 10));
                    worksheet.Column(5).Style.Font.SetFromFont(new System.Drawing.Font("나눔고딕", 10));
                    worksheet.Column(6).Style.Font.SetFromFont(new System.Drawing.Font("나눔고딕", 10));

                    worksheet.Row(1).Style.Font.Bold = true;
                    worksheet.Row(1).Style.Font.Size = 16;
                    worksheet.Row(1).Height = 30;

                    worksheet.Row(2).Style.Font.Size = 12;
                    worksheet.Row(2).Height = 24;

                    worksheet.Row(3).Style.Font.Bold = true;
                    worksheet.Row(3).Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
                    worksheet.Row(3).Style.Font.Size = 10;
                    worksheet.Row(3).Height = 18;

                    using (ExcelRange range = worksheet.Cells[string.Format("A3:F{0}", (cnt + 3).ToString())])
                    {
                        range.Style.Border.Top.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
                        range.Style.Border.Left.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
                        range.Style.Border.Right.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
                        range.Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
                    }
                    using (ExcelRange range = worksheet.Cells[string.Format("B3:C{0}", (cnt + 3).ToString())])
                    {
                        range.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
                    }
                    using (ExcelRange range = worksheet.Cells[string.Format("E3:E{0}", (cnt + 3).ToString())])
                    {
                        range.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
                    }
                    for (var x = 0; x < cnt + 3; x++)
                    {
                        worksheet.Row(x + 3).Height = 18;
                    }
                }
                // 비밀번호 pwd
                //excel.Encryption.Password = "pwd";
                // 내용을 엑셀파일로 저장
                excel.SaveAs(excelFile);
                // 저장위치 출력
                Console.WriteLine("SavePath : {0}", excelFile);
            }
        }
    }
}

19. 1. 14.

MSSQL 요일별, 주별 검색 쿼리 참고용

select datepart(week,datefield) as '주차'
,min(convert(char(10),datefield,120)) as '시작일'
,max(convert(char(10),datefield,120)) as '종료일'
,min(case when DATENAME(WEEKDAY,datefield)='일요일' then convert(char(10),datefield,120) end) as '일요일'
,min(case when DATENAME(WEEKDAY,datefield)='월요일' then convert(char(10),datefield,120) end) as '월요일'
,min(case when DATENAME(WEEKDAY,datefield)='화요일' then convert(char(10),datefield,120) end) as '화요일'
,min(case when DATENAME(WEEKDAY,datefield)='수요일' then convert(char(10),datefield,120) end) as '수요일'
,min(case when DATENAME(WEEKDAY,datefield)='목요일' then convert(char(10),datefield,120) end) as '목요일'
,min(case when DATENAME(WEEKDAY,datefield)='금요일' then convert(char(10),datefield,120) end) as '금요일'
,min(case when DATENAME(WEEKDAY,datefield)='토요일' then convert(char(10),datefield,120) end) as '토요일'
from searchTable
where datefield between '2018-01-01 00:00:00' and '2018-12-31 23:59:59'
group by datepart(week,datefield)
order by datepart(week,datefield)

내역이 제대로 들어가있으면 달력이된다.... ㅡ.ㅡ;;